Repository: angular
Issue: ComponentFixture.detectChanges causes NG0100 in zoneless mode
Labels: area: testing,area: core,core: change detection,core: zoneless

### Which @angular/* package(s) are the source of the bug?

core

### Is this a regression?

No

### Description

In zoneless mode, calling `ComponentFixture.detectChanges()` throws an NG0100 error.

Let's take the following component as an example:

```ts
@Component({
  selector: 'app-root',
  template: '{{ value }}',
})
export class AppComponent {
  value = 0;
}
```
 
I am well aware that in real life, since we use zoneless change detection, changing the value of the component should not trigger a change detection, because no signal is being modified.

Let's run the following (bad) test for it:

```ts
describe('AppComponent', () => {
  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [AppComponent],
      providers: [provideExperimentalZonelessChangeDetection()],
    }).compileComponents();
  });

  it('should detect changes', () => {
    const fixture = TestBed.createComponent(AppComponent);
    
    fixture.detectChanges();
    expect(fixture.nativeElement.textContent).toBe('0');

    fixture.componentInstance.value = 1;
    fixture.detectChanges();
    
    expect(fixture.nativeElement.textContent).toBe('1');
  });
});
```

When executed, I expect this test to pass, because we imperatively launch a change detection instead of letting Angular autodetect the changes.

But the test neither passes nor properly fails. Instead, it throws an NG0100 error.

The better test, letting Angular auto-detect the changes, fails correctly:

```ts
import { ComponentFixtureAutoDetect, TestBed } from '@angular/core/testing';
import { AppComponent } from './app.component';
import { provideExperimentalZonelessChangeDetection } from '@angular/core';

describe('AppComponent', () => {
  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [AppComponent],
      providers: [
        provideExperimentalZonelessChangeDetection(),
        { provide: ComponentFixtureAutoDetect, useValue: true },
      ],
    }).compileComponents();
  });

  it('should detect changes', async () => {
    const fixture = TestBed.createComponent(AppComponent);
    await fixture.whenStable();

    expect(fixture.nativeElement.textContent).toBe('0');

    fixture.componentInstance.value = 1;
    await fixture.whenStable();

    expect(fixture.nativeElement.textContent).toBe('1');
  });
});
```

### Please provide a link to a minimal reproduction of the bug

https://stackblitz.com/edit/stackblitz-starters-ah4pxu?file=demo%2Fsrc%2Fapp%2Fapp.component.spec.ts,demo%2Fsrc%2Fapp%2Fapp.component.better.spec.ts

### Please provide the exception or error you saw

```true
Error: NG0100: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: '0'. Current value: '1'. Expression location: AppComponent component. Find more at https://angular.dev/errors/NG0100
```

### Please provide the environment you discovered this bug in (run `ng version`)

```true
Angular CLI: 19.0.4
Node: 18.20.3
Package Manager: npm 10.2.3
OS: linux x64

Angular: 19.0.3
... animations, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, router

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1900.4
@angular-devkit/build-angular   19.0.4
@angular-devkit/core            19.0.4
@angular-devkit/schematics      19.0.4
@angular/cli                    19.0.4
@schematics/angular             19.0.4
rxjs                            7.8.1
typescript                      5.6.3
zone.js                         0.15.0
```

### Anything else?

To run the tests in the stackblitz:

- `cd demo`
- `npm i`
- `ng test`