Component unit testing in Angular 2/4 fails to register click events causing a lack of change detection

I'm currently working on testing a component in Angular 2/4 to determine if clicking on a button element will result in the desired changes. However, I'm facing an issue with triggering the click event.

Here is the component code:

import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy } 
from '@angular/core';

@Component({
    selector: 'input-filter',
    template: `
<div class="input-widget">
    <div class="icon-filter"></div>
    <input
        type="text"
        [value]="value"
        (input)="filter.emit($event.target.value)"
        placeholder="... filter"/>
    <span (click)="clear()" class="clear icon-clear-field_S"></span>
</div>
    `,
    changeDetection: ChangeDetectionStrategy.OnPush,
})

export class InputFilterComponent {
    @Input() value;
    @Output() filter = new EventEmitter(false);

    clear() {
        this.value = '';
        this.filterBoxes = [];
        this.filter.emit(this.value);
    }
}

And here is the test code:

import { TestBed } from '@angular/core/testing';
import { FormsModule } from '@angular/forms';
import { InputFilterComponent } from './input-filter.component';
import { Component} from '@angular/core';

const testValue = 'test1234';

@Component({
 selector  : 'test-cmp',
 template  : `<input-filter [value]="testValueC"></input-filter>`,
})
class TestCmpWrapper {
    testValueC = testValue; // mock input
}

describe('input-filter.component', () => {
    let fixture;

    beforeEach(() => {
        TestBed.configureTestingModule({
            imports: [FormsModule],
            declarations: [TestCmpWrapper, InputFilterComponent],
        });

        fixture = TestBed.createComponent(TestCmpWrapper);
    });

    it('should clear on click', () => {
        let testHostComponent = fixture.componentInstance;
        const el = fixture.debugElement.nativeElement;

        // both methods to trigger click do not work
        el.querySelector('.clear').click(); 
        el.querySelector('.clear').dispatchEvent(new Event('click'));

        fixture.detectChanges();

        fixture.whenStable().then(() => {
            expect(el.querySelector('input').value).toBe('');
        })
    });
});

HeadlessChrome 0.0.0 (Linux 0.0.0) input-filter.component should clear on click FAILED Expected 'test1234' to be ''.

Answer №1

Check out the code snippet below for a way to accomplish this task without using fakeAsync. Simply include fixture.detectChanges() before running your test code:

import { TestBed } from '@angular/core/testing';
import { FormsModule } from '@angular/forms';
import { InputFilterComponent } from './input-filter.component';
import { Component } from '@angular/core';

const testValue = 'test1234';

@Component({
  selector: 'test-cmp',
  template: `<input-filter [value]="testValueC"></input-filter>`,
})
class TestCmpWrapper {
  testValueC = testValue; // mock input
}

fdescribe('input-filter.component', () => {
  let fixture;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [FormsModule],
      declarations: [TestCmpWrapper, InputFilterComponent],
    });
    fixture = TestBed.createComponent(TestCmpWrapper);
  });

  it('should clear on click', () => {
    fixture.detectChanges();
    const testHostComponent = fixture.componentInstance;
    const el = fixture.debugElement.nativeElement;

    // Both methods to trigger click do not work
    el.querySelector('.clear').click();
    el.querySelector('.clear').dispatchEvent(new Event('click'));

    fixture.detectChanges();

    expect(el.querySelector('input').value).toBe('');
  });
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Mastering GraphQL querying in React using TypeScript

After successfully setting up a graphql and being able to use it in Postmen, here is how it looks: query listByName($name: String!) { listByName(name: $name) { id name sortOrder } } My variable is defined as {"name&quo ...

What is the reason a type is able to cast to an indexed collection when it is inferred, while an explicit type that seems identical is

I am puzzled by why my inferred types are considered as instances of my more general collection type while my explicit types are not. My goal was to: Have a specific part of my application work with tightly defined collections (e.g., IParents vs IBoss ...

JavaScript alert box

I'm fairly new to the world of web development, with knowledge in CSS & HTML and currently learning TypeScript. I'm attempting to create a message icon that opens and closes a notifications bar. Here's where I'm at so far: document.getE ...

Tips for resolving errors in Angular controls

Setting custom errors in Angular is straightforward with this code snippet: this.form.controls['field'].setErrors({same:true}); However, the process for removing custom errors is not as obvious. Does anyone know how to accomplish this? Are ther ...

Implementing a toggle feature with radio buttons for switching between true and false values in Angular using Reactive Forms and FormArray

Below is the radio button included in a FormArray: <input type="radio" formControlName="correctAnswer" value="" name="correctAnswer&quo ...

How to implement automatic clicking using Material Angular components

Looking to incorporate layout tabs from Angular Material into my project: https://material.angular.io/components/tabs/overview Interested in implementing auto-click functionality - how can I instruct Angular to simulate clicking on the "Tab1" link, waiti ...

Create a new object containing a series of function expressions, but exclude the first function parameter

In my current setup, I have a variable called storePattern const storePattern = { state: { }, mutations: { }, actions: {}, modules: { modal: { actions: { openModal(store, name: string): boolean { console.log('Op ...

Issue with Angular *ngIf not rendering properly following retrieval of data from API

I am experiencing an issue with the *ngIf directive. When I retrieve my data in the AppComponent and utilize *ngIf, my Revolution Slider does not display. Without using ngIf When using ngIf This is how my code appears: Service.ts getAllPlaces(languag ...

Creating a dynamic form with Angular 7 using ngFor and ngModel, incorporating validation through ngFrom attribute

I am currently working on developing an Angular input form that resembles a table. Here is my current approach: HTML: <form (ngSubmit)="doSomething()"> <table> <thead> <tr>First Name</tr> <tr>Last ...

Is it possible for me to connect an npm run command as a task in a Gruntfile?

In the root directory of my site, I have made changes to the package.json file by adding the "scripts" hook below: "scripts": { "ngDeployDev": "@powershell -NoProfile -ExecutionPolicy Unrestricted -Command ../../Scripts/ng-build-deploy/ngDeployDev.p ...

I want to know the most effective way to showcase particular information on a separate page using Angular

Recently, I've been working with a mock json file that contains a list of products to be displayed on a Product page. My goal is to select a specific product, such as 'Product 1', and have only that product's information displayed on th ...

Choosing and Duplicating Text in Angular

I'm attempting to give the user the ability to select a paragraph and copy it by clicking a button. However, my current code is not working as expected. I initially tried importing directives but encountered errors, prompting me to try a different met ...

Establishing the value of "document.cookie"

Encountering issues while trying to set a cookie using different methods: Method 1: document.cookie = name + "=" + value + "; expires=" + date.toUTCString() + "; path=/"; This method only sets the value up to "name=value" wh ...

Edge browser saves your most recent PDF viewing preferences

Within my Angular application, we have integrated a feature where users can view a PDF report downloaded via an API within an iFrame. .TS code: In the TypeScript code snippet provided, we are subscribing to the execution of the reportservice and handling ...

Manipulate dropdown choices by interacting with the dropdown form control in an Angular application

Is there a way to dynamically set options based on the form control name in Angular? For example, if we have a countries dropdown, we typically assign all countries to a specific variable and iterate over them using *ngFor. I am looking to change the opt ...

Leveraging ES6 Symbols in Typescript applications

Attempting to execute the following simple line of code: let INJECTION_KEY = Symbol.for('injection') However, I consistently encounter the error: Cannot find name 'Symbol'. Since I am new to TypeScript, I am unsure if there is somet ...

Why is it that when I try to create a table using the "Create Table" statement, I keep getting an error saying "Near '(': syntax error"?

Error : There seems to be a syntax error near "(". Here is the SQL statement causing the issue: CREATE TABLE IF NOT EXISTS tickets ( numero INTEGER PRIMARY KEY AUTOINCREMENT, identifier VARCHAR(4) NOT NULL, subject VARCHAR(150) NOT NULL, ...

Issue observed with the functionality of checkAll and uncheckAll after a user interacts with a single checkbox

After completing an Angular course on Udemy, I decided to implement a custom checkbox in my Angular app. However, I encountered an issue where the UI was not updating properly when using checkAll and uncheckAll functions after the user interacted with an i ...

Issue with vue-class-component: encountering TS2339 error when trying to call a method within

My vuejs application is being built using vue-cli-service. After a successful build, I encountered TS2339 errors in my webstorm IDE: Test.vue: <template> <div>{{method()}}</div> </template> <script lang="ts"> impor ...

Angularv9 - mat-error: Issue with rendering interpolated string value

I have been working on implementing date validation for matDatepicker and have run into an issue where the error messages do not show up when the start date is set to be greater than the end date. The error messages are supposed to be displayed using inter ...