-
Notifications
You must be signed in to change notification settings - Fork 27k
Description
Which @angular/* package(s) are the source of the bug?
core
Is this a regression?
No
Description
When using eventCoalescing: true in combination with fakeAsync, any event triggered will then block NgZone.onMicrotaskEmpty and .onStable for the rest of the test. Coalescing schedules change detection to be run in a way that the fake async zone cannot see, I think because of the Zone.root.run() used here. This causes the NgZone to be marked as having a microtask pending here, which never gets cleared. So as long as the zone thinks a microtask is pending it will never emit onMicrotaskEmpty nor onStable (see the check here).
Users do not need to use onMicrotaskEmpty or onStable directly to be affected. I noticed this when using an afterRender hook, which is internally triggered by onMicrotaskEmpty. Here is a repro showing that situation:
it('runs coalesced change detection', fakeAsync(() => {
let ranAfterRenderHook = false;
@Component({ standalone: true, selector: 'app-inner' })
class InnerComponent {
constructor() {
// this is an inner component so that we can register this hook _after_
// dispatching an event
afterRender(() => {
ranAfterRenderHook = true;
});
}
}
@Component({
standalone: true,
imports: [InnerComponent],
template: `
<div class="clickable" (click)="noop()"></div>
@if (showInner) {
<app-inner />
}
`,
})
class OuterComponent {
showInner = false;
noop = () => {};
}
TestBed.configureTestingModule({
// change this to `false` and the test passes
providers: [provideZoneChangeDetection({ eventCoalescing: true })],
});
const fixture = TestBed.createComponent(OuterComponent);
document.querySelector('.clickable')!.dispatchEvent(new MouseEvent('click'));
tick(); // you'd think this would flush the pending CD task, but it doesn't
fixture.componentInstance.showInner = true;
fixture.detectChanges();
tick(); // If afterRender is delayed, surely this should trigger it? Alas, no!
expect(ranAfterRenderHook).toBe(true);
}));Please provide a link to a minimal reproduction of the bug
No response
Please provide the exception or error you saw
No response
Please provide the environment you discovered this bug in (run ng version)
Angular CLI: 18.0.5
Node: 20.9.0
Package Manager: npm 10.1.0
OS: win32 x64
Angular: 18.0.4
... animations, cdk, common, compiler, compiler-cli, core, forms
... material, platform-browser, platform-browser-dynamic, router
Package Version
---------------------------------------------------------
@angular-devkit/architect 0.1800.5
@angular-devkit/build-angular 18.0.5
@angular-devkit/core 18.0.5
@angular-devkit/schematics 18.0.5
@angular/cli 18.0.5
@schematics/angular 18.0.5
ng-packagr 18.0.0
rxjs 7.8.1
typescript 5.4.5
zone.js 0.14.7
Anything else?
No response