0

My ng build command works fine. It is only when I run ng test that this error happens:

Error: Found the synthetic listener @transform.start. 
Please include either "BrowserAnimationsModule" or "NoopAnimationsModule" in your application.
error properties: Object({ ngDebugContext: DebugContext_({ view: Object({ def: Object({ factory: Function, nodeFlags: 36945921, rootNodeFlags: 33554433, nodeMatchedQueries: 0, flags: 0x: 0, outputIndex: 0, checkIndex: 0, flags: 33554433, childFlags: 3391488, directChildFlags: 3391488, childMatchedQueries: 0, matchedQueries: Object({  }), matchedQueryIds: 0, references: Objens: '', name: '@transform', nonMinifiedName: '@transform', securityContext: 0, suffix: undefined }) ], bindingFlags: 40, outputs: [ Object({ type: 0, target: 'component', eventName: '@transfor'@transform.done', propName: null }) ], element: Object({ ns: '', name: 'craft-app-sidenav', attrs: [  ], template: null, componentProvider: 
at checkNoSyntheticProp (http://localhost:9876/_karma_webpack_/C:/git/ttbt-craft/craft-angular/node_modules/@angular/platform-browser/fesm5/platform-browser.js:1198:1)
at EmulatedEncapsulationDomRenderer2.push.../../node_modules/@angular/platform-browser/fesm5/platform-browser.js.DefaultDomRenderer2.listen (http://localhost:9876/_karma_webpack_/Ctform-browser.js:1186:1)
...

I already found this question, which has the same error. However, the previous question is probably running ng build, and doesn't answer whether they've included the modules (which I have done here, so it didn't fix my issue.)

In my case, I added BrowserAnimationsModule to:

  1. app.module.ts
  2. app-sidenav.module.ts
  3. app-sidenav.component.spec.ts

Please note about above:

  • In the first two "normal" modules above, I imported BrowserAnimationsModule files and added BrowserAnimationsModule to the imports array directly as described here.
  • In the third module above, the "test" module, I imported BrowserAnimationsModule files and added BrowserAnimationsModule to the imports array via the beforeEach(async(() => { TestBed.configureTestingModule(...), as described here
  • I've repeated the above steps using NoopAnimationsModule instead of BrowserAnimationsModule, but still it doesn't work.
  • I've imported BrowserAnimationsModule after the BrowserModule (in the imports array), but I don't think order of imports matters...

Note the error complains about a synthetic listener (vs a synthetic property). I don't have any animations or HostListener or Angular Animations that I've defined in my code. However, I use Angular Material, and the error mentions @transform.start , which is defined in the MatSidenav component from the MatSidenavModule (I made sure to import the MatSidenavModule) I modified my components' animations property as suggested elsewhere (i.e. added the property animations: [matDrawerAnimations.transformDrawer] to my AppSidenavComponent, but it doesn't work).

My source code:

app-sidenav.component.spec.ts

import { CommonModule } from '@angular/common';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { MatSidenavModule } from '@angular/material';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule, NoopAnimationsModule } from '@angular/platform-browser/animations';
import { LayoutModule } from '@progress/kendo-angular-layout';
import { AppSidenavRoutingModule } from './app-sidenav-routing.module';

import { AppSidenavComponent } from './app-sidenav.component';
import { AppSidenavService } from './app-sidenav.service';

export const APP_SIDENAV_IMPORTS = [
  BrowserModule,
  BrowserAnimationsModule,

  CommonModule,
  AppSidenavRoutingModule,
  MatSidenavModule,
  LayoutModule,
];

describe('AppSidenavComponent', () => {
  let component: AppSidenavComponent;
  let fixture: ComponentFixture<AppSidenavComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: APP_SIDENAV_IMPORTS,
      declarations: [AppSidenavComponent],
      providers: [AppSidenavService]
    })
      .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(AppSidenavComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create including AnimationsModule', () => {
    expect(component).toBeTruthy();
  });
});

app-sidenav.component.ts

import { Component, OnInit, ElementRef, NgZone, Inject } from '@angular/core';
import { AppSidenavService } from './app-sidenav.service';
import { MatSidenav } from '@angular/material';
import { Platform } from '@angular/cdk/platform';
import { FocusTrapFactory, FocusMonitor, FocusOrigin } from '@angular/cdk/a11y';

// https://stackoverflow.com/a/37521339/1175496
import { DOCUMENT } from '@angular/common';
// THIS IS NOT USED BECAUSE IT WOULD NOT CREATE THE DIRECTIVE AND EXPAND IT,
// EVEN THWN I EXTENDS MATSIDENAV
@Component({
  selector: 'craft-app-sidenav',
  templateUrl: './app-sidenav.component.html',
  styleUrls: ['./app-sidenav.component.scss']
})
export class AppSidenavComponent extends MatSidenav implements OnInit {
  // constructor(_elementRef: ElementRef, _focusTrapFactory: FocusTrapFactory, _focusMonitor: FocusMonitor, _platform: Platform, _doc: any);

  public opened: boolean = true;
  // compiler.js:485 Uncaught Error: Can't resolve all parameters for AppSidenavComponent: ([object Object], [object Object], [object Object], [object Object], [object Object], ?).
  constructor(public appSidenavService: AppSidenavService,
    _elementRef: ElementRef,
    _focusTrapFactory: FocusTrapFactory,
    _focusMonitor: FocusMonitor,
    _platform: Platform,
    _ngZone: NgZone,
    @Inject(DOCUMENT) _doc: any
  ) {
    super(_elementRef, _focusTrapFactory, _focusMonitor, _platform, _ngZone, _doc);
  }

  ngOnInit() {
    this.toggle();
  }

}

app-sidenav.module.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

import { AppSidenavRoutingModule } from './app-sidenav-routing.module';
import { AppSidenavComponent } from './app-sidenav.component';
import { AppSidenavService } from './app-sidenav.service';

import  { MatSidenavModule } from '@angular/material';
import { LayoutModule } from '@progress/kendo-angular-layout';
import { APP_SIDENAV_IMPORTS } from './app-sidenav.component.spec';

@NgModule({
  imports: APP_SIDENAV_IMPORTS,
  exports : [
    AppSidenavComponent
  ],
  declarations: [AppSidenavComponent],
  providers: [AppSidenavService]
})
export class AppSidenavModule { }

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

import { AppComponent } from './app.component';
import { AppNewFeaturesComponent } from './app/app-new-features.component';

import { PageNotFoundComponent } from './page-not-found.component';

@NgModule({
  declarations: [
    AppComponent,
    PageNotFoundComponent,
    AppNewFeaturesComponent,
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
  ]

})
export class AppModule { }

EDIT When I use this technique (modifying compiler.js file, modifying the _loadModules function, to print the modules as they're loaded), I get output like the below (notice the BrowserAnimationsModule is among the modules listed! And yet still I have the error):

RootScopeModule
CommonModule
    NgClass
    NgComponentOutlet
    ...
ApplicationModule
BrowserModule
BrowserTestingModule
BrowserDynamicTestingModule
BrowserAnimationsModule
RouterModule
    RouterOutlet
    RouterLink
    ...
AppSidenavRoutingModule
BidiModule
    Dir
MatCommonModule
PlatformModule
ScrollingModule
    CdkFixedSizeVirtualScroll
    CdkScrollable
    ...
MatSidenavModule
    MatDrawer
    MatDrawerContainer
    ...
PanelBarModule
    PanelBarComponent
    PanelBarItemComponent
    ...
...
DynamicTestModule
    AppSidenavComponent
providers
   AppSidenavService
   TestBedViewEngine
   The presence of this token marks an injector as being the root injector.

Nate Anderson
  • 18,334
  • 18
  • 100
  • 135

1 Answers1

0

I made major changes since posting the question, and now my unit tests work better. Here are some relevant changes:

  • Upgrading Angular from version 8 to version 13
  • So I upgraded all core components like @angular/core, @angular/cli
  • And I upgraded all the key libraries I had to use, including @angular/material, and @progress (aka KendoUI)
  • Use an empty array for the styles option passed to the builder, when running tests empty array for styles option makes build run faster so angular karma tests can run
Nate Anderson
  • 18,334
  • 18
  • 100
  • 135