Search code examples
angularngx-bootstrapangular-test

Datepicker and Timepicker not initialised when the test runs


In my Angular app, I often use the datepicker and the timepicker components from ngx-bootstrap.

They work great, however apparently I'm unable to test them. The problem is that when my test case is running, those components are not initialised yet:

first line debugger

I set the breakpoint on the first line of my test case.

When the test case finishes to execute, I can see that the datepicker and timepicker components are correctly initialised:

enter image description here

My code is the following:

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

  beforeEach(async(() => {

    TestBed.configureTestingModule({
      declarations: [
        MyComponent,
        // ...
      ],
      imports: [
        BsDatepickerModule.forRoot(),
        TimepickerModule.forRoot(),
        // ...
      ],
      providers: [
        // ...
      ]
    })
      .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(MyComponent);
    component = fixture.componentInstance;
    fixture.autoDetectChanges(true);
  });

  it('some expectation here', () => {
    // whatever I put here, at this line the datepicker and timepicker will NOT be initialised
  });
});

how can I make my test case run AFTER that the datepicker and timepicker components have been initialised?


EDIT:

I did more investigations, the issue is about the [(ngModel)]="time" of the <timepicker> element basically it's being triggered only AFTER my test case exits.

how can I manually trigger it?

I tried with timepickerElement.dispatchEvent(new Event('input')); but it doesn't work.

also tried fixture.detectChanges(), fakeAsync+tick(), etc... but couldn't solve the issue.


Solution

  • The issue was that the [(ngModel)] directive for Datepicker and Timepicker was triggering only after that the test case was executed (because I'm wrapping them into a custom component that then it's used as a form control).

    To trigger that, I needed to add:

    datetimeElement.dispatchEvent(new Event('change'));
    timepickerElement.dispatchEvent(new Event('change'));
    fixture.detectChanges();
    

    after changing the values of the Datepicker and Timepicker elements.