Currently, I am in the process of developing a UI library in Angular 16. While creating a component like a textarea in my typescript file, I find that manipulating the DOM element at a logical level works smoothly. However, when attempting to write tests, the code consistently breaks at lines where the DOM is involved.
How can I effectively write tests for this scenario?
ts :
@ViewChild('myTextarea') myTextarea!: ElementRef<HTMLTextAreaElement>;
@Input() placeholderLabel?: string = 'label';
@Input() helperText?: string;
@Input() formGroup?: FormGroup;
@Input() formControlName?: string;
@Input() name: string;
@Input() disabled: boolean = false;
@Input() isWrongInput: boolean = false; // deprecated
@Input() hasError: boolean = false;
showHelperText: boolean = false;
showName: boolean = false;
tempPlaceholder: string = '';
ngOnInit(): void {
if (this.helperText) {
this.showHelperText = true;
}
this.tempPlaceholder = this.placeholderLabel;
}
onFocus() {
if (!this.disabled) {
this.showName = true;
this.placeholderLabel = '';
}
}
onBlur(event: any) {
if (!this.disabled) {
if (event.target.value == "") {
this.showName = false;
this.placeholderLabel = this.tempPlaceholder;
}
}
}
autoResizeTextarea() {
const textarea = this.myTextarea.nativeElement;
textarea.style.height = 'auto';
textarea.style.height = `${textarea.scrollHeight}px`;
if (textarea.style.height !== '44px') {
textarea.style.lineHeight = '24px';
this.autoResizeTextarea();
if (textarea.style.height === '80px') {
textarea.style.lineHeight = '52px';
}
}
if (textarea.style.height === '44px' || textarea.style.height === undefined) {
textarea.style.lineHeight = '38px';
}
}
My Spec Test
describe('CaInputTextComponent', () => {
let component: CaTextAreaComponent;
let fixture: ComponentFixture<CaTextAreaComponent>;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
CaTextAreaComponent,
],
});
fixture = TestBed.createComponent(CaTextAreaComponent);
component = fixture.componentInstance;
});
// Test to verify component creation
it('Should create the component', () => {
expect(component).toBeTruthy();
});
// Test to check if the label is displayed in the template
it('Should display the label in the template', () => {
component.placeholderLabel = 'Test';
fixture.detectChanges();
const labelElement = fixture.nativeElement.querySelector('.input');
expect(labelElement.placeholder).toContain('Test');
});
// Test for onFocus event click
it('Should emit click event with the correct value', () => {
const labelElement = fixture.nativeElement.querySelector('.input');
component.placeholderLabel = 'Test';
component.onFocus();
expect(component.placeholderLabel).toEqual('');
expect(labelElement.placeholder).toEqual('');
});
// Test for onBlur event click
it('Should emit click event with the correct value', () => {
const labelElement = fixture.nativeElement.querySelector('.input');
const event = {
target: {
value: ''
}
};
component.onBlur(event);
fixture.detectChanges();
expect(component.showName).toEqual(false);
expect(labelElement.placeholder).toBe(component.tempPlaceholder);
});
it('Should display helper text correctly', () => {
component.helperText = 'test';
component.ngOnInit();
fixture.detectChanges();
expect(component.helperText).toEqual('test');
expect(component.showHelperText).toEqual(true);
});
it('Should resize the textarea properly', () => {
component.myTextarea.nativeElement.value = 'Sss';
component.autoResizeTextarea();
expect(component.myTextarea.nativeElement.style.height).toBe(`${component.myTextarea.nativeElement.scrollHeight}px`);
// Add other expectations based on your specific requirements
});
});
My Error:
TypeError: Cannot read properties of undefined (reading 'nativeElement') at UserContext.apply...
Line of Error: component.myTextarea.nativeElement.value = 'Sss';