Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bug(MatSnackBarHarness): Testing a snack bar with a duration #19290

Open
ersimont opened this issue May 8, 2020 · 8 comments
Open

bug(MatSnackBarHarness): Testing a snack bar with a duration #19290

ersimont opened this issue May 8, 2020 · 8 comments
Labels
area: material/snack-bar P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent

Comments

@ersimont
Copy link

ersimont commented May 8, 2020

Reproduction

https://stackblitz.com/edit/components-issue-v9512z?file=src%2Fapp%2Fexample-test.spec.ts

Steps to reproduce:

  1. Try to e.g. await harness.getMessage() a snack bar that was opened with a duration. You can see this simply by following the link above, which will run that automatically.

Expected Behavior

The harness returns the message in the snack bar.

Actual Behavior

The test hangs for the duration that the snack bar is open, then fails with "Failed to find element".

Environment

  • Angular: 9.1.5
  • CDK/Material: 9.2.2
  • Browser(s): Chrome
  • Operating System (e.g. Windows, macOS, Ubuntu): Windows

Commentary

Using the same test code, I can test a snack bar that was opened without a duration. But if my production code does use a duration it does not appear possible to test it with the harness. Am I missing something? I assume assigning a duration is a common use-case.

@ersimont ersimont added the needs triage This issue needs to be triaged by the team label May 8, 2020
@devversion devversion added this to Triaged in triage #1 via automation May 25, 2020
@devversion devversion added area: material/snack-bar P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent and removed needs triage This issue needs to be triaged by the team labels May 25, 2020
@devversion devversion assigned devversion and unassigned devversion May 25, 2020
@mmalerba mmalerba added this to Needs triage in Component Harnesses Jun 16, 2020
@mmalerba mmalerba moved this from Needs triage to High priority in Component Harnesses Jun 25, 2020
@stijnvn
Copy link
Contributor

stijnvn commented Mar 10, 2021

I can confirm this is still an issue with

  • Angular: 11.1.1
  • Material: 11.1.1

@bluemagma612
Copy link

I am having this issue as well, any ideas as to a work around?

@ersimont
Copy link
Author

My "workaround" involves using a whole test library (that I wrote). It runs test in the fakeAsync zone and does not flush timeouts before searching for harnesses. You can use the AngularContext for testing e.g. services, and ComponentContext for components.

For an example that uses MatSnackBar, you can see this test

@qlassalle
Copy link

qlassalle commented Mar 12, 2022

The issue is still present with:

  • Angular 13.2.5
  • Material 13.2.5

Trying to retrieve the harness with await loader.getHarness(MatSnackBarHarness) fails with:

Error: Failed to find element matching one of the following queries:
(MatSnackBarHarness with host element matching selector: ".mat-snack-bar-container")

Also, as described ersimont, the test is still hanging for the duration the snackbar is open.

If it's not planned to fix it any time soon, it would be nice to indicate in the doc that this Harness is broken to avoid people wasting time on it, and wondering why their test is failing (what I experimented this morning).

@dkimmich-onventis
Copy link

The issue is still present with Angular v15 and the MDC-based Snack Bar.

@ashwynnair
Copy link

I had the same issue on Angular 14.2.12 and Material 14.2.7. Getting the error:

Error: Failed to find element matching one of the following queries:
(MatSnackBarHarness with host element matching selector: ".mat-snack-bar-container")

when using await loader.getHarness(MatSnackBarHarness)

@shawn40611
Copy link

It still had the same issue on Angular 16.2.12 and Material 16.2.14, and I got a workaround to fix it by simply wrap harness code block into fakeAsync:

it('can test snack bars', async () => {
    fixture.componentInstance.sayHello();
    fakeAsync(() => {
      const snackBar = await loader.getHarness(MatSnackBarHarness);
      expect(await snackBar.getMessage()).toBe('Hello!');
    })();  // must invoke the returned function
  });

@blockerdude
Copy link

I ran into this problem recently and I've come up with a solution which I believe is easy and fast.
As a note: My test environment uses Jest, but I think other testing frameworks would also work in a similar way.

Instead of using a harness to get the snackbar, just spy on it instead.

    snackSpy = jest.spyOn(TestBed.inject(MatSnackBar), 'open').mockReturnValue(null)
    // important to return null, otherwise the test will wait for the snackbar to close

You can then test the snackbar opening with specific values in a few ways

    // test everything
    expect(snackSpy).toHaveBeenCalledWith('Some message', 'Close', { duration: 2000 })

    // only test the message
    expect(snackSpy.mock.lastCall[0]).toEqual('abc123')

You might also have some success experimenting with jest.useFakeTimers() but that might be getting a bit too specific for this question.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: material/snack-bar P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent
Projects
Component Harnesses
  
High priority
triage #1
  
Triaged
Development

No branches or pull requests

9 participants