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:
CodePudding user response:
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.
CodePudding user response:
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',