jeudi 17 janvier 2019

Testing working Angular component - TypeError: $(...).somename is not a function

I have problem while testing my component - spec.ts is autogenerated file that I'm using to test. What is weird is that my components works fine - I was testing this for a while, but every time I try to test it as "yarn run test" I'm getting error:

HeadlessChrome 0.0.0 (Windows 10 0.0.0) DaterangepickerComponent should create FAILED
    TypeError: $(...).datepicker is not a function
        at DaterangepickerComponent.initializeDatepicker (./src/app/ifs/shared/daterangepicker/daterangepicker.component.ts?:70:45)
        at DaterangepickerComponent.ngAfterViewInit (./src/app/ifs/shared/daterangepicker/daterangepicker.component.ts?:64:14)
        at callProviderLifecycles (./node_modules/@angular/core/fesm5/core.js?:19323:18)
        at callElementProvidersLifecycles (./node_modules/@angular/core/fesm5/core.js?:19297:13)
        at callLifecycleHooksChildrenFirst (./node_modules/@angular/core/fesm5/core.js?:19287:29)
        at checkAndUpdateView (./node_modules/@angular/core/fesm5/core.js?:20223:5)
        at callWithDebugContext (./node_modules/@angular/core/fesm5/core.js?:21108:25)
        at Object.debugCheckAndUpdateView [as checkAndUpdateView] (./node_modules/@angular/core/fesm5/core.js?:20786:12)
        at ViewRef_.detectChanges (./node_modules/@angular/core/fesm5/core.js?:18595:22)
        at ComponentFixture._tick (./node_modules/@angular/core/fesm5/testing.js?:253:32)

I really don't know why I'm getting this while it works fine in application. Maybe someone can give me advice how to fix it.

component.spec.ts:

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

beforeEach(async(() => {
TestBed.configureTestingModule({
  declarations: [ DaterangepickerComponent ],
    imports: [
        StoreModule.forRoot(appReducers),
        EffectsModule.forRoot([DatabaseEffects]),
        HttpClientModule,
        HttpClientTestingModule,
        ReactiveFormsModule,
        NgSelectModule,
        TranslateModule.forRoot({
            loader: {
                provide: TranslateLoader,
                useFactory: HttpLoaderFactory,
                deps: [HttpClient]
            }
        })
    ]
})
.compileComponents();
}));

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

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

And this is how my component looks like, its wrapped bootstrap-datepicker library for daterangepicker:

declare var $;


@Component({
selector: 'cb-daterangepicker',
templateUrl: './daterangepicker.component.html',
styleUrls: ['./daterangepicker.component.scss']
})
export class DaterangepickerComponent implements OnInit, AfterViewInit, OnChanges {

private _options: DatepickerOptions;
private _isLoaded: boolean;
private _datepicker: any;
private _startDate: string;
private _endDate: string;


@Input()
set datepickerOptions(value: DatepickerOptions) {
    this._options = value;
};

@Input()
set defaultStartDate(value: string) {
    this._startDate = value;
    this.updatePicker();
}

@Input()
set defaultEndDate(value: string) {
    this._endDate = value;
    this.updatePicker();
}

@Input()
range = new DateRange();

@Input()
clear$: Observable<any>;

@Output()
rangeValue = new EventEmitter<DateRange>();


updatePicker() {

    if (!this._isLoaded) {
        this._isLoaded = true;
        this.initializeDatepicker();
    }

    $('#dateFrom').datepicker('setStartDate', this._startDate);
    $('#dateFrom').datepicker('setEndDate', this._endDate);

    $('#dateTo').datepicker('setEndDate', this._endDate);
    $('#dateTo').datepicker('setStartDate', this._startDate);

}

constructor() {
    this.onChangeDate = this.onChangeDate.bind(this);
}

ngOnInit() {
}

ngOnChanges(changes) {
}

ngOnDestroy() {
}

ngAfterViewInit(): void {
    this._isLoaded = true;
    this.initializeDatepicker();
}

initializeDatepicker() {
    if (!this._isLoaded) {
        return;
    }

    this._datepicker = $('#datepicker').datepicker(this._options);
    $('#dateFrom').datepicker('setDate', this._startDate);
    $('#dateTo').datepicker('setDate', this._endDate);
    this._datepicker.on('changeDate', this.onChangeDate);
}

onChangeDate() {
    this.range.startDate = $('#dateFrom').datepicker('getDate');
    this.range.endDate = $('#dateTo').datepicker('getDate');

    if (!this.range.startDate) {
        $('#dateFrom').datepicker('setDate', this._startDate);
    }

    this.rangeValue.emit(this.range)
}
}

Aucun commentaire:

Enregistrer un commentaire