angularangular-materialcypresscypress-component-test-runner

Cyprus component testing of angular stand alone component with material UI gives BrowserAnimationsModule import error


I am using stand alone components in a lazy loaded route for my angular app. When I ng serve the app, everything works properly. The main app is using modules, but all other comps are stand alone.

The problem is when I try to use Cyprus component testing for one of these lazy stand alone components.

The component that generates an error uses material ui elements (table, inputs, sort, pagination etc). Something in this component giving me the following error during testing:

(uncaught exception)Error: Unexpected synthetic listener @arrowPosition.start found. Please make sure that:

  • Either BrowserAnimationsModule or NoopAnimationsModule are imported in your application.
  • There is corresponding configuration for the animation named @arrowPosition.start defined in the animations field of the @Component decorator

here is my comp code:

import {
  AfterViewInit, ChangeDetectionStrategy, Component, EventEmitter, Input, Output,
  ViewChild,
} from '@angular/core';
import { CommonModule } from '@angular/common';
import { MatTableDataSource, MatTableModule } from '@angular/material/table';
import { MatPaginator } from '@angular/material/paginator';
import { MatPaginatorModule } from '@angular/material/paginator';
import { MatSort, MatSortModule } from '@angular/material/sort';
import { PersonalRecordListItem } from '@t3/data/domain/shared';
import { PrimaryContentCardComponent } from '@t3/training-tracker-web/ui-shared';
import { MatInputModule } from '@angular/material/input';

@Component({
  selector: 't3-personal-records-list',
  imports: [
    CommonModule,
    MatTableModule,
    MatPaginatorModule,
    MatSortModule,
    MatInputModule,
    PrimaryContentCardComponent,
  ],
  templateUrl: './personal-records-list.component.html',
  styleUrls: ['./personal-records-list.component.scss'],
  standalone: true,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class PersonalRecordsListComponent implements AfterViewInit {
  @ViewChild(MatPaginator)
  paginator!: MatPaginator;
  @ViewChild(MatSort) sort!: MatSort;

  @Input() tabelData: PersonalRecordListItem[] = [];
  @Output() selectedRowChanged = new EventEmitter<string>();

  dataSource = new MatTableDataSource<PersonalRecordListItem>();
  displayedColumns: string[] = ['date', 'name', 'displayValue'];

  ngAfterViewInit() {
    this.dataSource = new MatTableDataSource(this.tabelData);
    this.dataSource.paginator = this.paginator;
    this.dataSource.sort = this.sort;
  }

  applyFilter(event: Event) {
    const filterValue = (event.target as HTMLInputElement).value;
    this.dataSource.filter = filterValue.trim().toLowerCase();

    if (this.dataSource.paginator) {
      this.dataSource.paginator.firstPage();
    }
  }

  selectRow(rowItem: PersonalRecordListItem) {
    this.selectedRowChanged.emit(rowItem.id);
  }
}

So I tried to add the following to the component declaration:

providers: [provideAnimations()],

but the error remains

If I add BrowserAnimationsModule to the component imports I get the following error:

Providers from the BrowserModule have already been loaded. If you need access to common directives such as NgIf and NgFor, import the CommonModule instead.

BrowserAnimationsModule is imported into the main app.module so that is why the error does not appear when serving the app, only when testing its stand alone components

EDIT 1:

I tired to add provideAnimations() to the cy.ts file:

describe(PersonalRecordsListComponent.name, () => {
  beforeEach(() => {
    TestBed.overrideComponent(PersonalRecordsListComponent, {
      add: {
        imports: [],
        providers: [provideAnimations()],
      },
    });
  });

This does not solve the error.

If I add AnimationsModule to the cypress file like this:

    imports: [BrowserAnimationsModule],
    providers: [],

I get the already provided error I mentioned above.

Can someone help me get Cyprus component testing working here?


Solution

  • I came back to this problem after a while.

    THe problem was that for cypress component tests, the NoopAnimationsModule needs to be imported in the individual "it" tests. FOr some reason, adding it to the overrideComponent does not work.

    here is what worked in the end, this is inside the describe block:

      it('should exist', () => {
        cy.mount(RowCellComponent, {
          imports: [NoopAnimationsModule],
        })
          .get('[cy-data="dropdown"]')
          .should('exist');
      });
    

    simplified code