Reputation: 13206
My test for the component below keeps failing with the error message:
HeadlessChrome 78.0.3882 (Windows 10.0.0) LoginButtonGroupComponent : should have option to sign in with Google FAILED
Failed: Cannot read property 'innerText' of null
However it passes for the should have option to sign in with email address
test. Any idea what is wrong?
Test
import { LoginButtonGroupComponent } from './login-button-group.component';
import { FormsModule } from '@angular/forms';
import { async, inject, TestBed } from '@angular/core/testing';
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { TestStore } from '../../../core/core.spec';
import { State } from '../../../core/store/auth/auth.reducer';
import { Store } from '@ngrx/store';
describe('LoginButtonGroupComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
imports: [FormsModule],
providers: [
{ provide: Store, useClass: TestStore }
],
declarations: [LoginButtonGroupComponent]
}).compileComponents().then(() => {
});
}));
describe(':', () => {
let fixture, app;
let store: TestStore<State>;
beforeEach((inject([Store], (testStore: TestStore<State>) => {
store = testStore;
store.setState({user: null, error: null});
fixture = TestBed.createComponent(LoginButtonGroupComponent);
app = fixture.debugElement.componentInstance;
})));
afterEach(() => {
fixture.destroy();
app = null;
});
it('should create the component', async(() => {
expect(app).toBeTruthy();
}));
it('should have option to sign in with Google', async(() => {
expect(document.getElementById('googleSignIn').innerText.trim()).toBe('Sign in with Google');
}));
it('should have option to sign in with Facebook', async(() => {
expect(document.getElementById('facebookSignIn').innerText.trim()).toBe('Sign in with Facebook');
}));
it('should have option to sign in with email address', async(() => {
expect(document.getElementById('emailSignIn').innerText.trim()).toBe('or use your email address');
}));
});
});
Component
<p [ngClass]="setButtonAlignment(position)">
<button (click)="googleSignIn()" *ngIf="!(isMobile | async)?.matches" class="btn btn-label btn-google"
type="button">
<label id="googleSignIn">
<fa-icon [icon]="['fab', 'google']" size="xs"></fa-icon>
</label> Sign in with Google
</button>
<button (click)="mobileGoogleSignIn()" *ngIf="(isMobile | async)?.matches" class="btn btn-label btn-google"
type="button">
<label id="mobileGoogleSignIn">
<fa-icon [icon]="['fab', 'google']" size="xs"></fa-icon>
</label> Sign in with Google
</button>
<button (click)="facebookSignIn()" *ngIf="!(isMobile | async)?.matches" class="btn btn-label btn-facebook"
type="button">
<label id="facebookSignIn">
<fa-icon [icon]="['fab', 'facebook-f']" size="xs"></fa-icon>
</label> Sign in with Facebook
</button>
<button (click)="mobileFacebookSignIn()" *ngIf="(isMobile | async)?.matches" class="btn btn-label btn-facebook"
type="button">
<label id="mobileFacebookSignIn">
<fa-icon [icon]="['fab', 'facebook-f']" size="xs"></fa-icon>
</label> Sign in with Facebook
</button>
</p>
<p [ngClass]="setButtonAlignment(position)">
<small>
<a class="text-muted small-2" id="emailSignIn" routerLink="/register">or use your email address <fa-icon
[icon]="['fas', 'long-arrow-alt-right']" size="xs"></fa-icon>
</a>
</small>
</p>
Upvotes: 0
Views: 707
Reputation: 101
I think this button doesn't exist in a moment when this test run's because you render it with async pipe. Try to use detectChanges(), maybe this will help you:
it('should have option to sign in with Facebook', async(() => {
component = fixture.componentInstance;
component.ngOnInit();
fixture.detectChanges();
expect(document.getElementById('facebookSignIn').innerText.trim()).toBe('Sign in with Facebook');
}));
I really wonder why it not working for you. I have tried to simulate a similar situation and everything works fine.
export interface IsMobile {
matches: string;
}
export class UserProfileComponent implements OnInit {
isMobile: Observable<IsMobile>;
breikPoint = new BehaviorSubject<IsMobile>(null);
ngOnInit(): void {
this.isMobile = this.breikPoint.asObservable();
}
changeView() {
// simulate change the view
this.breikPoint.next({matches: '320'});
}
}
<button id="facebook" (click)="changeView()" *ngIf="!(isMobile | async)?.matches">Click</button>
it('should display button and hide after ckick', async(() => {
component = fixture.componentInstance;
component.ngOnInit();
fixture.detectChanges();
const button = fixture.debugElement.query(By.css('#facebook'));
expect(button.nativeElement.innerText).toEqual('Click');
button.triggerEventHandler('click', null);
fixture.detectChanges();
const buttonAfterClick = fixture.debugElement.query(By.css('#facebook'));
expect(buttonAfterClick).toEqual(null);}));
Upvotes: 1