`ng-apexcharts` causing unit test failures

I've been working on integrating apexcharts and ng-apexcharts into my home component. While I was able to get it up and running smoothly, it seems to be causing issues with my unit tests. Despite researching possible solutions, I haven't been able to find a fix for the error that occurs during cleanup.

HomeComponent:

@Component({
  selector: 'hu-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.scss'],
  standalone: true,
  imports: [
    NavbarComponent,
    BarChartComponent
  ],
})
export class HomeComponent {}

home html:

<hu-navbar></hu-navbar>
<hu-bar-chart test-id="bar-chart"></hu-bar-chart>

BarChartComponent:

@Component({
  selector: 'hu-bar-chart',
  standalone: true,
  imports: [CommonModule, NgApexchartsModule],
  templateUrl: './bar-chart.component.html',
  styleUrls: ['./bar-chart.component.scss'],
})
export class BarChartComponent {
  @Input() series: ApexAxisChartSeries | ApexNonAxisChartSeries;
  @Input() chart: ApexChart;

  constructor() {
    this.series = [...];
    this.chart = {...};
  }
}

bar chart html:

<apx-chart test-id="bar-chart" [series]="series" [chart]="chart"></apx-chart>

HomeComponent's spec file:

describe('HomeComponent', () => {
  let component: HomeComponent;
  let fixture: ComponentFixture<HomeComponent>;
  let authenticationMock: AuthenticationMockService; // use mock to decouple unit tests from Firebase
  let page: HTMLElement;

  beforeEach(async () => {
    authenticationMock = new AuthenticationMockService();

    await TestBed.configureTestingModule({
      imports: [HomeComponent],
    })
      .overrideProvider(AuthenticationService, { useValue: authenticationMock })
      .compileComponents();

    fixture = TestBed.createComponent(HomeComponent);
    fixture.detectChanges();

    component = fixture.componentInstance;
    page = fixture.debugElement.nativeElement;
  });

  it('should create', () => {
    fixture.whenStable().then(() => {
      expect(component).toBeTruthy();
    });
  });

  it('should show the navbar', () => {
    expect(navbar()).not.toBeNull();
  });

  it('should show the bar chart', () => {
    expect(barChart()).not.toBeNull();
  });

  function navbar() {
    return page.querySelector('hu-navbar');
  }

  function barChart() {
    return page.querySelector('[test-id="bar-chart"]');
  }
});

And finally, the error:

console.error
    Error during cleanup of component {
      component: HomeComponent { __ngContext__: 7 },
      stacktrace: TypeError: Cannot read properties of undefined (reading 'node')
      ...

This error persists across all tests. I attempted to resolve it by adding a cleanup step as follows:

  afterEach(() => {
    setTimeout(() => {
      fixture.destroy();
    }, 100);
  });

However, this did not solve the issue. I am considering mocking it as a potential solution, but have yet to find information on how to do so.

There is a similar question on Stack Overflow regarding testing react-apexcharts, though it does not pertain to ng-apexcharts.

Answer №1

To address this issue, it is recommended to insert the provided code snippet into your .spec.ts file. This snippet should be placed within the automatically generated beforeEach function that comes with the ng generate command:

beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [...],
    }).compileComponents();

    // The following code block should be added
    Object.defineProperty(window, 'ResizeObserver', {
      writable: true,
      value:
        window.ResizeObserver ||
        jest.fn().mockImplementation(() => ({
          observe: jest.fn(),
          unobserve: jest.fn(),
          disconnect: jest.fn(),
        })),
    });

    Object.defineProperty(global.SVGElement.prototype, 'getScreenCTM', {
      writable: true,
      value: jest.fn(),
    });

    Object.defineProperty(global.SVGElement.prototype, 'createSVGMatrix', {
      writable: true,
      value: jest.fn().mockReturnValue({
        x: 10,
        y: 10,
        // eslint-disable-next-line @typescript-eslint/no-empty-function
        inverse: () => {},
        // eslint-disable-next-line @typescript-eslint/no-empty-function
        multiply: () => {},
      }),
    });
    // End of code insertion
   
    fixture = TestBed.createComponent(TheComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

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

Exploring the Benefits of Utilizing Cypress to Verify Form Fields and Manage Errors within Angular (version 13.3.0)

Recently started using Cypress with Angular version 13.3.0 and facing a validation issue with a form. Upon clicking a button, the form opens displaying various validation rules like 'First Name is required', 'Last Name', 'Gender&ap ...

Mastering the Art of Adding Headers in Angular

Here is the Angular service code: getCareer(dataout: any){ let headers = new HttpHeaders().append('Content-Type', 'application/json').append('Authorization','Bearer'+' '+GlobalService.authToken); //hea ...

I am encountering a TypeScript error with URLSearchParams. The object cannot be successfully converted to a string using the toString() method

During the development of my react app with postgres, express, node, and typescript, I ran into an issue while working on the backend code. The problem arises when trying to utilize URLSearchParams. index.js import express from 'express'; import ...

"Learn the steps to seamlessly add text at the current cursor position with the angular-editor tool

How can I display the selected value from a dropdown in a text box at the current cursor position? I am currently using the following code: enter code selectChangeHandler(event: any) { this.selectedID = event.target.value; // console.log("this.selecte ...

Unable to personalize map controls in OpenLayer mapping system

Having trouble styling custom map controls with CSS selectors .ol-zoom-in and .ol-zoom-out. Any suggestions on how to customize them? export class CustomMapControlsComponent implements OnInit { map: Map | undefined; constructor() {} ngOnInit() ...

The metadata for Company#companyTypesLinks could not be located. Please verify that the entity object has been correctly specified

I am facing an issue with the relationship between my entities. I have tried everything, but I still encounter the same problem. Here are my scripts: Company.entity.ts export class Company extends AppBaseEntity { @Column('text', { name: ' ...

Extract information from a complex nested structure within an array

Can someone assist me with extracting only the username from the response provided below? I am able to access other data but struggling with this particular aspect. [ { "_id": "5f44d450aaa72313549d519f", "imageTitle": "u ...

Should I link my Angular Material 2 data table to AngularFire2 or Firebase service?

Trying to make this work has been quite the struggle. I've spent hours experimenting, but nothing seems to be working as expected. The md data table is relatively new, so there isn't much information available online yet. Connecting Firebase to t ...

Whenever I attempt to reload a page on my Angular http-server, I receive a "Page Not Found" error

Whenever I try to refresh a page on my Angular application running on an http-server, the browser displays a "Page Not Found" error. Can anyone provide assistance with resolving this issue? ...

Fixing Typescript assignment error: "Error parsing module"

Trying to assign an object to the variable initialState, where the type of selectedActivity is Activity | undefined. After using the Nullish Coalescing operator (??), the type of emptyActivity becomes Activity. However, upon execution of this line, an err ...

Can the Okta Sign-In Widget be tailored to incorporate Angular Material elements?

I’ve recently integrated the @okta/okta-signin-widget into my Angular SPA, and it displays as follows: <span> <input id="okta-signin-username" type="text"> </span> My Angular SPA is styled using the Angular Mate ...

An issue within the component.ts file is preventing Angular from correctly rendering the content

As a newcomer to Angular, I encountered an issue when trying to run my angular app. Instead of displaying the content as expected, all I see is a blank page. Upon inspecting it, I noticed that the app-root element was empty. So, I decided to take a look at ...

Convert an object to nested JSON in Angular 5

I am struggling with using Angular 5 HttpClient to send a post request because I am having trouble casting an object to nested JSON. For instance, I have the following class: export class Team { members: Person[]; constructor(members: Person[]) ...

Connecting the outcome of a Promise with an Observable

Forgive me if this is a silly question. I searched high and low but couldn't find the answer I need. I'm trying to figure out how to pass the value for index, which is returned in the Promise, as an argument to my Observable: deleteFavorite(tok ...

JavaScript: Employ array destructuring for improved code readability (eslintprefer-destructuring)

How can I resolve the ESLint error that says "Use array destructuring. eslint(prefer-destructuring)"? The error occurs on this line of my code: let foo = 1; foo = obj.data[i][1]; //ESLint error on this line If anyone could provide assistance in fixing thi ...

typescript create object with immutable property already set

Can you create an object literal in JavaScript and define its interface with read-only properties simultaneously? For instance let obj = { readonly prop1: 'hello', readonly prop2: 'world' } ...

Angular 5: experiencing issues with HttpClient when using REST API

Currently, I am in the process of developing a REST API using Spring to perform CRUD operations based on a tutorial I found. However, I have encountered an issue with the HTTP client not retrieving data, and upon inspection, I discovered the following erro ...

Hosting a web application like it's the main directory in ASP.NET from a subfolder

I am currently developing an Angular 2 application that is hosted on a basic ASP.NET WebApplication. The code for the entire project is bundled up neatly in one folder using webpack. However, whenever I need to redeploy the Angular app, I find myself havin ...

Show a select element with choices that change depending on another select element

I am currently working on a select dropdown component that utilizes the @Input option variable. My goal is to have another instance of this component display options based on the selection made in the first instance. Any suggestions on how to make this h ...

Top strategies for sharing methods among various components in Angular 8

Suppose there's a function that calculates the percentage from two given numbers: calculatePercentage(a, b) { return (((a - b) / b) * 100 * 2).toFixed(2); } Currently, this function resides in the component controller. How can I make it re ...