Skip to content

Endless loop in waitFor #230

Closed
Closed
@jbchr

Description

@jbchr

Hello 👋,,

we have the issue that some of our testing-library tests get stuck in an endless loop but only when they fail.

I could track down the issue to the waitFor function and to all functions that use it under the hood such as findBy*.

Furthermore, I think the issue is related to the internal usage of MutationObserver in waitFor by DTL to trigger the callback inside waitFor. But also how ATL wraps the waitFor function.

One idea i have that it might be related to this issue in DTL that suggests that you shouldn't do DOM mutations inside the waitFor but this is what can happen in the detectChanges call:
https://github.com/testing-library/angular-testing-library/blob/main/projects/testing-library/src/lib/testing-library.ts#L314

You can reproduce the issue in this simple test:

@Component({
  selector: 'atl-fixture',
  template: `
    <button [ngClass]="classes">Load</button>
  `,
})
class LoopComponent {
  get classes() {
    return {
      someClass: true,
    };
  }
}

test('does not end up in a loop', async () => {
  await render(LoopComponent);

  await waitForATL(() => {
    expect(true).toEqual(false);
  });
});

This should time out but is stuck in a loop. If I manually remove the mutationObserver code in the waitFor function from testing-library-dom the issue is gone. However, I think this issue still belongs to this library as it is angular specific.

Edit: This issue in the angular repository might also indicate what is going wrong here

Edit2: I'm pretty sure now it works like this: ATL detectChanges causes CD cycle => get classes() returns new object => DOM mutation => mutationObserver triggers => DTL triggers callback => triggers ATL detectChanges again. My solution for now is to remove MutationObserver code from DTL using patch-package as I prefer slower tests to reliable tests. We could open request to DTL to make mutationObserver optional, or maybe you have a better idea. I'm also willing to create a PR if we can come up with a feasible solution.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions