简体   繁体   English

测试 Jasmine 中的 Ionic Toast 按钮单击

[英]Testing Ionic Toast button click in Jasmine

I am unable to query for one of the Toast buttons inside while testing.在测试时,我无法查询里面的 Toast 按钮之一。 It simply returns null .它只是返回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.在测试结果中,我可以看到正在创建的 toast,其中.retry-button类被设置为所需的按钮。

I am stumped, I believe that maybe the tests are being run before the Toast elements are being created.我很难过,我相信也许测试是在创建 Toast 元素之前运行的。

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?会不会是 HTML 元素不在fixture.debugElement上,而是在文档上?

Try the following (query by nativeElement):尝试以下操作(通过 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.这应该等到.retry-button在 DOM 中,然后再继续。

The problem is the Toast button is actually a part of the shadow DOM.问题是 Toast 按钮实际上是 shadow DOM 的一部分。 I was able to come to a working solution by accessing the correct shadow DOM:通过访问正确的影子 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:我还在 ToastController 的htmlAttributes属性中设置了 id 以确保一致性:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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