简体   繁体   中英

Testing Ionic Toast button click in Jasmine

I am unable to query for one of the Toast buttons inside while testing. It simply returns null . The class is set, and that is what is being used to query.

it('should make a call to retrieval method on retry', async () => {
      spyOn(component, 'retrieveEntry');

      await component.retryRetrieval();
      fixture.detectChanges();

      await fixture.whenStable();

      const retryButton = fixture.debugElement.query(By.css('.retry-button'));
      retryButton.nativeElement.click();
      fixture.detectChanges();

      expect(component.retrieveEntry).toHaveBeenCalled();
});

In the test results I can see the toast being created, with the class of .retry-button being set to the desired button.

I am stumped, I believe that maybe the tests are being run before the Toast elements are being created.

Here's the test result, as you can see the button is being added with the appropriate class:

在此处输入图像描述

That's a very strange issue.

Could it be that the HTML element is not on the fixture.debugElement but on the document?

Try the following (query by nativeElement):

const retryButton = fixture.nativeElement.querySelector('.retry-button');
retryButton.click();

If the above doesn't work, try the following (query by document):

const retryButton = document.querySelector('.retry-button');
retryButton.click();

If none of the above works, then it could be that the element is getting painted asynchronously at a later point in time.

You can use this answer to help where you can do:

await waitUntil(() => !!document.querySelector('.retry-button'));

That should wait until .retry-button is in the DOM before continuing.

The problem is the Toast button is actually a part of the shadow DOM. I was able to come to a working solution by accessing the correct shadow DOM:

it('should make a call to retrieval method on retry', async () => {
      spyOn(component, 'retrieveEntry');

      await component.retryRetrieval();
      fixture.detectChanges();

      const host = document.getElementById('retry-toast');
      const root = host.shadowRoot;
      const retryButton = root.querySelector('.retry-button') as HTMLElement;

      retryButton.click();
      fixture.detectChanges();

      expect(component.retrieveEntry).toHaveBeenCalled();
    });

I also set the id in htmlAttributes property in the ToastController to ensure consistency:

const toast = await this.toastController.create({
      message: 'An error occurred retrieving entry.',
      htmlAttributes: {
        id: 'retry-toast'
      },
      color: 'danger',

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM