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

fix(core): ComponentFixture stability should match ApplicationRef #54949

Closed
wants to merge 1 commit into from

Conversation

atscott
Copy link
Contributor

@atscott atscott commented Mar 19, 2024

This change aligns the stability of ComponentFixture with that of ApplicationRef, preventing confusing differences between the two as more APIs start using the PendingTasks that may not be tracked by NgZone.

BREAKING CHANGE: ComponentFixture.whenStable now matches the
ApplicationRef.isStable observable. Prior to this change, stability
of the fixture did not include everything that was considered in
ApplicationRef. whenStable of the fixture will now include unfinished
router navigations and unfinished HttpClient requests. This will cause
tests that await the whenStable promise to time out when there are
incomplete requests. To fix this, remove the whenStable,
instead wait for another condition, or ensure HttpTestingController
mocks responses for all requests. Try adding HttpTestingController.verify()
before your await fixture.whenStable to identify the open requests.
Also, make sure your tests wait for the stability promise. We found many
examples of tests that did not, meaning the expectations did not execute
within the test body.

In addition, ComponentFixture.isStable would synchronously switch to
true in some scenarios but will now always be asynchronous.

@atscott atscott added area: testing Issues related to Angular testing features, such as TestBed breaking changes area: core Issues related to the framework runtime target: major This PR is targeted for the next major release labels Mar 19, 2024
@ngbot ngbot bot modified the milestone: Backlog Mar 19, 2024
@atscott atscott added the requires: TGP This PR requires a passing TGP before merging is allowed label Mar 19, 2024
@angular-robot angular-robot bot added the detected: breaking change PR contains a commit with a breaking change label Mar 19, 2024
@atscott atscott force-pushed the fixturestable branch 4 times, most recently from 6d934e0 to 8a0b725 Compare March 20, 2024 15:51
This change aligns the stability of `ComponentFixture` with that of
`ApplicationRef`, preventing confusing differences between the two as
more APIs start using the `PendingTasks` that may not be tracked by
`NgZone`.

BREAKING CHANGE: `ComponentFixture.whenStable` now matches the
`ApplicationRef.isStable` observable. Prior to this change, stability
of the fixture did not include everything that was considered in
`ApplicationRef`. `whenStable` of the fixture will now include unfinished
router navigations and unfinished `HttpClient` requests. This will cause
tests that `await` the `whenStable` promise to time out when there are
incomplete requests. To fix this, remove the `whenStable`,
instead wait for another condition, or ensure `HttpTestingController`
mocks responses for all requests. Try adding `HttpTestingController.verify()`
before your `await fixture.whenStable` to identify the open requests.
Also, make sure your tests wait for the stability promise. We found many
examples of tests that did not, meaning the expectations did not execute
within the test body.

In addition, `ComponentFixture.isStable` would synchronously switch to
true in some scenarios but will now always be asynchronous.
Copy link
Contributor

@AndrewKushnir AndrewKushnir left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

packages/core/test/component_fixture_spec.ts Show resolved Hide resolved
Copy link
Contributor

@AndrewKushnir AndrewKushnir left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed-for: public-api

@pullapprove pullapprove bot requested a review from dylhunn March 26, 2024 18:23
@atscott atscott added the action: merge The PR is ready for merge by the caretaker label Mar 27, 2024
Copy link
Contributor

@dylhunn dylhunn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reviewed-for: fw-core, public-api, fw-forms

@dylhunn
Copy link
Contributor

dylhunn commented Mar 27, 2024

This PR was merged into the repository by commit 658cf8c.

@dylhunn dylhunn closed this in 658cf8c Mar 27, 2024
atscott added a commit to atscott/angular that referenced this pull request Mar 27, 2024
…the `HttpBackend`

This commit updates the approach to how the `http` package contributes
to application stability by moving the contribution point from an
interceptor wrapper to the backend.

`HttpClient` uses the `PendingTasks` service to contribute to
application stability. This was added in v16 to support SSR without
relying on an infinite `setTimeout` with ZoneJS like it did pre-v16.
Prior to version 16, this was also only done on the server and did not
affect clients or unit tests.

Prior to angular#54949, `PendingTasks` contribute to `ApplicationRef.isStable` but did not
contribute to the stability of `ComponentFixture`. This divergence in
stability behavior was not intended. By aligning the two behaviors again, this
includes all pending tasks in the stability of fixtures. This is
likely to be a pretty large breaking change test with `HttpClient`.
Tests appear to quite often use `await fixture.whenStable` when there are
unfinished requests that have not been mocked or flushed.

This change prevents request in `HttpClient` from contributing to
stability through the `PendingTasks` in tests by not including the stability
contribution in the mock backend. In this scenario, requests need to be
flushed manually for them to resolve, which is problematic for existing
test suites which do not flush them before `await fixture.whenStable`.

BREAKING CHANGE: `HttpClient` interceptors are no longer contribute directly to
`ApplicationRef.isStable` without ZoneJS. `ApplicationRef.isStable` is
used for SSR to determine when to serialize the application. If there is
async work in interceptors that is not captured by ZoneJS and needs to
be included in the SSR serialization, these should be updated to keep
the zone unstable by running a timeout inside the zone and clearing it when
the async interceptor work is finished.
atscott added a commit to atscott/angular that referenced this pull request Mar 27, 2024
…the `HttpBackend`

This commit updates the approach to how the `http` package contributes
to application stability by moving the contribution point from an
interceptor wrapper to the backend.

`HttpClient` uses the `PendingTasks` service to contribute to
application stability. This was added in v16 to support SSR without
relying on an infinite `setTimeout` with ZoneJS like it did pre-v16.
Prior to version 16, this was also only done on the server and did not
affect clients or unit tests.

=== Additional background information ===

Prior to angular#54949, `PendingTasks` contribute to `ApplicationRef.isStable` but did not
contribute to the stability of `ComponentFixture`. This divergence in
stability behavior was not intended. By aligning the two behaviors again, this
includes all pending tasks in the stability of fixtures. This is
likely to be a pretty large breaking change test with `HttpClient`.
Tests appear to quite often use `await fixture.whenStable` when there are
unfinished requests that have not been mocked or flushed.

This change prevents request in `HttpClient` from contributing to
stability through the `PendingTasks` in tests by not including the stability
contribution in the mock backend. In this scenario, requests need to be
flushed manually for them to resolve, which is problematic for existing
test suites which do not flush them before `await fixture.whenStable`.

BREAKING CHANGE: `HttpClient` interceptors are no longer contribute directly to
`ApplicationRef.isStable` without ZoneJS. `ApplicationRef.isStable` is
used for SSR to determine when to serialize the application. If there is
async work in interceptors that is not captured by ZoneJS and needs to
be included in the SSR serialization, these should be updated to keep
the zone unstable by running a timeout inside the zone and clearing it when
the async interceptor work is finished.
atscott added a commit to atscott/angular that referenced this pull request Mar 27, 2024
…the `HttpBackend`

This commit updates the approach to how the `http` package contributes
to application stability by moving the contribution point from an
interceptor wrapper to the backend.

`HttpClient` uses the `PendingTasks` service to contribute to
application stability. This was added in v16 to support SSR without
relying on an infinite `setTimeout` with ZoneJS like it did pre-v16.
Prior to version 16, this was also only done on the server and did not
affect clients or unit tests. (angular@28c68f7)

=== Additional background information ===

Prior to angular#54949, `PendingTasks` contribute to `ApplicationRef.isStable` but did not
contribute to the stability of `ComponentFixture`. This divergence in
stability behavior was not intended. By aligning the two behaviors again, this
includes all pending tasks in the stability of fixtures. This is
likely to be a pretty large breaking change test with `HttpClient`.
Tests appear to quite often use `await fixture.whenStable` when there are
unfinished requests that have not been mocked or flushed.

This change prevents request in `HttpClient` from contributing to
stability through the `PendingTasks` in tests by not including the stability
contribution in the mock backend. In this scenario, requests need to be
flushed manually for them to resolve, which is problematic for existing
test suites which do not flush them before `await fixture.whenStable`.

BREAKING CHANGE: `HttpClient` interceptors are no longer contribute directly to
`ApplicationRef.isStable` without ZoneJS. `ApplicationRef.isStable` is
used for SSR to determine when to serialize the application. If there is
async work in interceptors that is not captured by ZoneJS and needs to
be included in the SSR serialization, these should be updated to keep
the zone unstable by running a timeout inside the zone and clearing it when
the async interceptor work is finished.
atscott added a commit to atscott/angular that referenced this pull request Mar 27, 2024
…the `HttpBackend`

This commit updates the approach to how the `http` package contributes
to application stability by moving the contribution point from an
interceptor wrapper to the backend.

`HttpClient` uses the `PendingTasks` service to contribute to
application stability. This was added in v16 to support SSR without
relying on an infinite `setTimeout` with ZoneJS like it did pre-v16.
Prior to version 16, this was also only done on the server and did not
affect clients or unit tests. (angular@28c68f7)

=== Additional background information ===

Prior to angular#54949, `PendingTasks` contribute to `ApplicationRef.isStable` but did not
contribute to the stability of `ComponentFixture`. This divergence in
stability behavior was not intended. By aligning the two behaviors again, this
includes all pending tasks in the stability of fixtures. This is
likely to be a pretty large breaking change test with `HttpClient`.
Tests appear to quite often use `await fixture.whenStable` when there are
unfinished requests that have not been mocked or flushed.

This change prevents request in `HttpClient` from contributing to
stability through the `PendingTasks` in tests by not including the stability
contribution in the mock backend. In this scenario, requests need to be
flushed manually for them to resolve, which is problematic for existing
test suites which do not flush them before `await fixture.whenStable`.

BREAKING CHANGE: `HttpClient` interceptors are no longer contribute directly to
`ApplicationRef.isStable` without ZoneJS. `ApplicationRef.isStable` is
used for SSR to determine when to serialize the application. If there is
async work in interceptors that is not captured by ZoneJS and needs to
be included in the SSR serialization, these should be updated to keep
the zone unstable by running a timeout inside the zone and clearing it when
the async interceptor work is finished.
atscott added a commit to atscott/angular that referenced this pull request Mar 28, 2024
…the `HttpBackend`

This commit updates the approach to how the `http` package contributes
to application stability by moving the contribution point from an
interceptor wrapper to the backend.

`HttpClient` uses the `PendingTasks` service to contribute to
application stability. This was added in v16 to support SSR without
relying on an infinite `setTimeout` with ZoneJS like it did pre-v16.
Prior to version 16, this was also only done on the server and did not
affect clients or unit tests. (angular@28c68f7)

=== Additional background information ===

Prior to angular#54949, `PendingTasks` contribute to `ApplicationRef.isStable` but did not
contribute to the stability of `ComponentFixture`. This divergence in
stability behavior was not intended. By aligning the two behaviors again, this
includes all pending tasks in the stability of fixtures. This is
likely to be a pretty large breaking change test with `HttpClient`.
Tests appear to quite often use `await fixture.whenStable` when there are
unfinished requests that have not been mocked or flushed.

This change prevents request in `HttpClient` from contributing to
stability through the `PendingTasks` in tests by not including the stability
contribution in the mock backend. In this scenario, requests need to be
flushed manually for them to resolve, which is problematic for existing
test suites which do not flush them before `await fixture.whenStable`.

BREAKING CHANGE: `HttpClient` interceptors are no longer contribute directly to
`ApplicationRef.isStable` without ZoneJS. `ApplicationRef.isStable` is
used for SSR to determine when to serialize the application. If there is
async work in interceptors that is not captured by ZoneJS and needs to
be included in the SSR serialization, these should be updated to keep
the zone unstable by running a timeout inside the zone and clearing it when
the async interceptor work is finished.
atscott added a commit to atscott/angular that referenced this pull request Apr 1, 2024
…the `HttpBackend`

This commit updates the approach to how the `http` package contributes
to application stability by moving the contribution point from an
interceptor wrapper to the backend.

`HttpClient` uses the `PendingTasks` service to contribute to
application stability. This was added in v16 to support SSR without
relying on an infinite `setTimeout` with ZoneJS like it did pre-v16.
Prior to version 16, this was also only done on the server and did not
affect clients or unit tests. (angular@28c68f7)

=== Additional background information ===

Prior to angular#54949, `PendingTasks` contribute to `ApplicationRef.isStable` but did not
contribute to the stability of `ComponentFixture`. This divergence in
stability behavior was not intended. By aligning the two behaviors again, this
includes all pending tasks in the stability of fixtures. This is
likely to be a pretty large breaking change test with `HttpClient`.
Tests appear to quite often use `await fixture.whenStable` when there are
unfinished requests that have not been mocked or flushed.

This change prevents request in `HttpClient` from contributing to
stability through the `PendingTasks` in tests by not including the stability
contribution in the mock backend. In this scenario, requests need to be
flushed manually for them to resolve, which is problematic for existing
test suites which do not flush them before `await fixture.whenStable`.

BREAKING CHANGE: `HttpClient` interceptors are no longer contribute directly to
`ApplicationRef.isStable` without ZoneJS. `ApplicationRef.isStable` is
used for SSR to determine when to serialize the application. If there is
async work in interceptors that is not captured by ZoneJS and needs to
be included in the SSR serialization, these should be updated to keep
the zone unstable by running a timeout inside the zone and clearing it when
the async interceptor work is finished.
ilirbeqirii pushed a commit to ilirbeqirii/angular that referenced this pull request Apr 6, 2024
…angular#54949)

This change aligns the stability of `ComponentFixture` with that of
`ApplicationRef`, preventing confusing differences between the two as
more APIs start using the `PendingTasks` that may not be tracked by
`NgZone`.

BREAKING CHANGE: `ComponentFixture.whenStable` now matches the
`ApplicationRef.isStable` observable. Prior to this change, stability
of the fixture did not include everything that was considered in
`ApplicationRef`. `whenStable` of the fixture will now include unfinished
router navigations and unfinished `HttpClient` requests. This will cause
tests that `await` the `whenStable` promise to time out when there are
incomplete requests. To fix this, remove the `whenStable`,
instead wait for another condition, or ensure `HttpTestingController`
mocks responses for all requests. Try adding `HttpTestingController.verify()`
before your `await fixture.whenStable` to identify the open requests.
Also, make sure your tests wait for the stability promise. We found many
examples of tests that did not, meaning the expectations did not execute
within the test body.

In addition, `ComponentFixture.isStable` would synchronously switch to
true in some scenarios but will now always be asynchronous.

PR Close angular#54949
atscott added a commit to atscott/angular that referenced this pull request Apr 8, 2024
…the `HttpBackend`

This commit updates the approach to how the `http` package contributes
to application stability by moving the contribution point from an
interceptor wrapper to the backend.

`HttpClient` uses the `PendingTasks` service to contribute to
application stability. This was added in v16 to support SSR without
relying on an infinite `setTimeout` with ZoneJS like it did pre-v16.
Prior to version 16, this was also only done on the server and did not
affect clients or unit tests. (angular@28c68f7)

=== Additional background information ===

Prior to angular#54949, `PendingTasks` contribute to `ApplicationRef.isStable` but did not
contribute to the stability of `ComponentFixture`. This divergence in
stability behavior was not intended. By aligning the two behaviors again, this
includes all pending tasks in the stability of fixtures. This is
likely to be a pretty large breaking change test with `HttpClient`.
Tests appear to quite often use `await fixture.whenStable` when there are
unfinished requests that have not been mocked or flushed.

This change prevents request in `HttpClient` from contributing to
stability through the `PendingTasks` in tests by not including the stability
contribution in the mock backend. In this scenario, requests need to be
flushed manually for them to resolve, which is problematic for existing
test suites which do not flush them before `await fixture.whenStable`.

BREAKING CHANGE: `HttpClient` interceptors are no longer contribute directly to
`ApplicationRef.isStable` without ZoneJS. `ApplicationRef.isStable` is
used for SSR to determine when to serialize the application. If there is
async work in interceptors that is not captured by ZoneJS and needs to
be included in the SSR serialization, these should be updated to keep
the zone unstable by running a timeout inside the zone and clearing it when
the async interceptor work is finished.
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Apr 27, 2024
@pullapprove pullapprove bot removed the requires: TGP This PR requires a passing TGP before merging is allowed label Apr 27, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker area: core Issues related to the framework runtime area: testing Issues related to Angular testing features, such as TestBed breaking changes detected: breaking change PR contains a commit with a breaking change target: major This PR is targeted for the next major release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants