Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How-to interact with ng-boostrap modal in Jasmine test

I'm using bootstrap 4 with the angular @ng-bootstrap library https://ng-bootstrap.github.io/#/components/modal. I have written a simple confirm popup modal message, as follows:

<div id='modalContainer' ngbModalContainer class="modal-content" aria-labelledby='ModalConfirmPopup'  aria-describedby='message'>
  <div class="modal-header">
    <h4 id='title' class="modal-title">Confirm</h4>
    <button id='dismissButton' type="button" class="close" aria-label="Close" (click)="activeModal.dismiss(false)">
      <span aria-hidden="true">&times;</span>
    </button>
  </div>
  <div class="modal-body">
    <p id='message'>{{ message }}</p>
  </div>
  <div class="modal-footer">
    <button id='okButton' type='button' class='btn btn-primary' (click)='activeModal.close(true)'>OK</button>
    <button id='cancelButton' type='button' class='btn btn-warning' (click)='activeModal.close(false)'>Cancel</button>
  </div>
</div>

typescript:

import { Component, Input } from '@angular/core';
import { NgbModal, NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
//
@Component({
  selector: 'app-confirm4',
  templateUrl: './confirm4.component.html'
})
export class Confirm4Component {
  //
  @Input() message;
  constructor(public activeModal: NgbActiveModal) {}
  //
}

Interestingly, one dynamically instantiates the component. Because of the dynamic component, one is required to add the component to @NgModule entryComponents, also in the Jasmine test.

My problem is testing the component with Jasmine. The first 10 lines of my ‘should test’ contains the basic code used in the hosting component, that wishes to confirm an action. It instantiates the component and handles both response and dismissal.

it('should response with true when click the ok button...', async(() => {
  let response: boolean;
  const modalRef = modalService.open( Confirm4Component );
  modalRef.componentInstance.message = 'click ok button';
  modalRef.result.then((userResponse) => {
    console.log(`User's choice: ${userResponse}`)
    response = userResponse;
  }, (reason) => {
    console.log(`User's dismissed: ${reason}`)
    response = reason;
  });
  // now what?
  expect( response ).toEqual( true );
}));

Normally, one would:

fixture = TestBed.createComponent( Confirm4Component );

but that creates a new instance. So, how do I click the Ok button?

like image 668
Phil Huhn Avatar asked Oct 29 '22 06:10

Phil Huhn


1 Answers

I was locally prompted at the SEMJS meetup to look at the NgbModal Jasmine tests. My solution is as follows:

it('should response with true when click the ok button...', async(() => {
  console.log( 'Click ok button' );
  let response: boolean;
  modalRef.componentInstance.message = 'Click Ok button';
  modalRef.result.then((userResponse) => {
    this.response = userResponse;
    console.log(`Button clicked: ${userResponse}`)
  }, (reason) => {
    this.response = reason;
    console.log(`X clicked: ${reason}`)
  });
  let ok = (<HTMLElement>document.querySelector('#okButton'));
  ok.click();
  setTimeout( () => {
      expect( this.response ).toEqual( true );
    }, 10);
}));
like image 120
Phil Huhn Avatar answered Nov 15 '22 06:11

Phil Huhn