testing-library/angular-testing-library

Can't click on button inside mat-sidenav when using fakeAsync

Closed this issue · 1 comments

Can't click on button inside sidenav when using fakeAsync.

Simple example:

import { render, screen } from "@testing-library/angular"
import userEvent from "@testing-library/user-event"

import { fakeAsync } from "@angular/core/testing"
import { MatSidenavModule } from "@angular/material/sidenav"

describe("Test", () => {
  test("Click button sidenav", fakeAsync(async () => {
    await render(
      `
      <ng-container>
        <mat-sidenav-container>
            <mat-sidenav [opened]="true" position="end" mode="over" role="complementary">
                <button data-testid="test-button">test</button>
            </mat-sidenav>
            <mat-sidenav-content>
              <div></div>
            </mat-sidenav-content>
        </mat-sidenav-container>
      </ng-container>
      `,
      { imports: [MatSidenavModule] }
    )

    const user = userEvent.setup()

    await screen.findByTestId("test-button")

    await user.click(screen.getByTestId("test-button"))
  }))
})

getting:

Error: 1 timer(s) still in the queue.

with these lib versions:

"@angular/core": "15.2.9",
"@testing-library/angular": "14.5.1",
"@testing-library/user-event": "14.5.2",
"@angular/material": "15.2.9",

EDIT:
If I don't use fakeAsync it works.
If I use jest.useFakeTimers() I have the same problem, I have to call jest.useRealTimers() before the user.click if I want to make it work again.

@KarmaCop213 fakeAsync is a bit tricky, and I won't recommend it.
See #438 for an example with jest fake timers.
The trick is to make user-event aware of the timers, and provide the advanceTimers method a way to advance the fake time:

  const user = userEvent.setup({
    advanceTimers: jest.advanceTimersByTime,
  });