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

perf(platform-browser): avoid including Testability by default in bootstrapApplication #45885

Conversation

AndrewKushnir
Copy link
Contributor

@AndrewKushnir AndrewKushnir commented May 5, 2022

The Testability-related logic was refactored in #45657 to become tree-shaking-friendly: it was decoupled from the core providers of the BrowserModule. This commit updates the newly-introduced bootstrapApplication function to exclude Testability-providers by default (note: the Testability is still included in the NgModule-based bootstrap).

In order to add the Testability to the app bootstrapped via bootstrapApplication, the withProtractorTestingSupport function is introduced.

PR Type

What kind of change does this PR introduce?

  • Other... Please describe: performance improvement

Does this PR introduce a breaking change?

  • Yes
  • No, since the bootstrapApplication function is not released yet (will be released in v14).

@AndrewKushnir AndrewKushnir added state: WIP area: core Issues related to the framework runtime core: performance target: rc This PR is targeted for the next release-candidate cross-cutting: standalone Issues related to the NgModule-less world labels May 5, 2022
@ngbot ngbot bot modified the milestone: Backlog May 5, 2022
@AndrewKushnir AndrewKushnir force-pushed the exclude_testability_in_standalone_bootstrap branch 2 times, most recently from efde95e to f2b0f6d Compare May 5, 2022 01:45
@AndrewKushnir
Copy link
Contributor Author

Note: CI indicates ~3.5kb of payload size savings for minified version (but before gzip):

Commit f2b0f6da2c20b84dfdfc8a88a2801dfa41a9e22e uncompressed
main fell below expected size by 500 bytes or >1% (expected: 87940, actual: 84237).

@AndrewKushnir AndrewKushnir force-pushed the exclude_testability_in_standalone_bootstrap branch 2 times, most recently from 5683a51 to a3ce7e2 Compare May 7, 2022 02:04
alxhub
alxhub previously approved these changes May 9, 2022
@AndrewKushnir AndrewKushnir force-pushed the exclude_testability_in_standalone_bootstrap branch from a3ce7e2 to f1a7cfe Compare May 9, 2022 22:35
@AndrewKushnir AndrewKushnir marked this pull request as ready for review May 9, 2022 22:35
@AndrewKushnir AndrewKushnir added action: review The PR is still awaiting reviews from at least one requested reviewer and removed state: WIP labels May 9, 2022
@AndrewKushnir
Copy link
Contributor Author

Update: I've performed manual testing with the following e2e tools (that are presented as options in ng e2e):

  • Cypress (@cypress/schematic)
  • Nightwatch (@nightwatch/schematics)
  • WebdriverIO (@wdio/schematics)

All of them work correctly with the bootstrapApplication-based setup without Testability, so it should not be a problem for users switching to bootstrapApplication.

For Protractor users, this PR adds the withProtractorTestingSupport function that can be used to add Testability providers into the app.

@AndrewKushnir
Copy link
Contributor Author

Presubmit.

@AndrewKushnir AndrewKushnir added the action: presubmit The PR is in need of a google3 presubmit label May 9, 2022
jessicajaniuk
jessicajaniuk previously approved these changes May 9, 2022
Copy link
Contributor

@jessicajaniuk jessicajaniuk 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, integration-tests, public-api, size-tracking

@@ -235,6 +235,9 @@ export class TransferState {
// @public (undocumented)
export const VERSION: Version;

// @public
export function withProtractorTestingSupport(): Provider[];
Copy link
Member

Choose a reason for hiding this comment

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

I'm kind of iffy on this function starting with with, since I've usually only seen this used with builder-style APIs.

Why not just protractorTestingSupport? That way its use in providers reads like "provide protractor testing support"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the review @jelbourn 👍

The function will only be used (or rather makes sense) in a context of bootstrapping an app and the call site would look like this:

const appRef = bootstrapApplication(
  RootStandaloneComponent,
  {providers: [withProtractorTestingSupport()]}
);

So we bootstrap an app with protractor testing support - this is where the with prefix comes from. We plan to use similar prefixes for other things (like withRouter, etc). Please let us know what do you think.

// cc @alxhub

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, I looked at the usage in the PR. I think that this is inconsistent with how providers like this are normally named and that it's not clear what with is modifying. It would be different if it were e.g.

bootstrapApplication(RootStandaloneComponent, providers: [...])
    .withProtractorSupport();

In that scenario, the with makes sense because it's clearly modifying the bootstrap call. (This builder-style API of course defeats the point of tree-shaking). But providers are traditionally more "noun-y". If you mix this API with other providers, the mismatch stands out:

const appRef = bootstrapApplication(
  RootStandaloneComponent,
  {providers: [
    UserDataClient,
    SideChannelDispatcher,
    withProtractorTestingSupport()
  ]}
);

I read this code like:
"Provide a user data client"
"Provide a side channel dispatcher"
"Provider a with protractor testing support"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

After some additional discussions, the function was renamed to provideProtractorTestingSupport. We'll have another round of discussions and finalize the name during the RC phase (before v14 final release).

atscott
atscott previously approved these changes May 9, 2022
Copy link
Contributor

@atscott atscott 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: size-tracking

Withholding public API review so as to not cut short the ongoing conversation about the naming.

dylhunn
dylhunn previously approved these changes May 9, 2022
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: public-api, size-tracking

But as atscott I don't intend to cut off the conversation above.

* which requires Testability. Testability is not included by default when
* the `bootstrapApplication` function is used (which is the case in this app).
* We use this app primarily to measure payload size, so we want to keep
* Testability excluded.
Copy link
Member

Choose a reason for hiding this comment

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

should we have this e2e test / e2e testing infrastructure at all then? Or even this integration/standalone-bootstrap integration test at all? It seems like we are trying to have 2 things covered by this "app":

  • size tracking;
  • actual integration testing of the bootstrap operation.

It seems like those 2 needs are in conflict somehow?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@pkozlowski-opensource currently those two parts (size tracking and e2e tests) are bundled together in one build rule:

ng_integration_test(
name = "test",
setup_chromium = True,
track_payload_size = "standalone-bootstrap",
)

Ideally we'd need to decouple them into 2 separate build rules, so that we have more flexibility in terms of configuration. Once it's done, we can refactor the usage here to just leverage the size-tracking piece.

…otstrapApplication`

The Testability-related logic was refactored in angular#45657 to become tree-shaking-friendly: it was decoupled from the core providers of the `BrowserModule`. This commit updates the newly-introduced `bootstrapApplication` function to exclude Testability-providers by default (note: the Testability is still included in the NgModule-based bootstrap).

In order to add the Testability to the app bootstrapped via `bootstrapApplication`, the `provideProtractorTestingSupport` function is introduced.
@AndrewKushnir AndrewKushnir force-pushed the exclude_testability_in_standalone_bootstrap branch from f1a7cfe to 07a6eb4 Compare May 10, 2022 18:34
@AndrewKushnir AndrewKushnir removed action: review The PR is still awaiting reviews from at least one requested reviewer action: presubmit The PR is in need of a google3 presubmit labels May 10, 2022
Copy link
Member

@alxhub alxhub 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

Copy link
Member

@pkozlowski-opensource pkozlowski-opensource 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

Copy link
Contributor

@jessicajaniuk jessicajaniuk 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, integration-tests, public-api, size-tracking

@AndrewKushnir AndrewKushnir added the action: merge The PR is ready for merge by the caretaker label May 10, 2022
@AndrewKushnir
Copy link
Contributor Author

This PR was merged into the repository by commit 3165fa3.

AndrewKushnir added a commit that referenced this pull request May 10, 2022
…otstrapApplication` (#45885)

The Testability-related logic was refactored in #45657 to become tree-shaking-friendly: it was decoupled from the core providers of the `BrowserModule`. This commit updates the newly-introduced `bootstrapApplication` function to exclude Testability-providers by default (note: the Testability is still included in the NgModule-based bootstrap).

In order to add the Testability to the app bootstrapped via `bootstrapApplication`, the `provideProtractorTestingSupport` function is introduced.

PR Close #45885
dgp1130 added a commit to dgp1130/angular-cli that referenced this pull request May 11, 2022
After angular/angular#45885, testability now needs to be explicitly added to `bootstrapApplication()`.
dgp1130 added a commit to angular/angular-cli that referenced this pull request May 11, 2022
After angular/angular#45885, testability now needs to be explicitly added to `bootstrapApplication()`.
dgp1130 added a commit to dgp1130/angular-cli that referenced this pull request May 11, 2022
After angular/angular#45885, testability now needs to be explicitly added to `bootstrapApplication()`.

(cherry picked from commit 329a2a3)
dgp1130 added a commit to angular/angular-cli that referenced this pull request May 11, 2022
After angular/angular#45885, testability now needs to be explicitly added to `bootstrapApplication()`.

(cherry picked from commit 329a2a3)
@StanislavKharchenko
Copy link

@AndrewKushnir Thanks for your response.
What generally will be with Testability functionality?
Do you plan to continue supporting it in the future?
We asking about it since rely on this functionality in our selenium e2e infrastructure.

Thanks.

@AndrewKushnir
Copy link
Contributor Author

What generally will be with Testability functionality?
Do you plan to continue supporting it in the future?

@StanislavKharchenko the Testability was primarily designed to support Protractor, which is now deprecated. We are considering Testability deprecation as well, but we'll need to do some additional analysis first to understand if there are any critical use-cases that it covers which can not be handled by using other APIs.

If we end up deprecating the Testability classes, there will be an additional communication (via release notes and updates to the deprecations page) and the classes will be available for a long period of time, so developers can transition to other APIs.

We asking about it since rely on this functionality in our selenium e2e infrastructure.

Could you please share a bit more on how you use Testability in your e2e infrastructure and whether there are existing replacement APIs (provided by Angular) that you can consider?

@StanislavKharchenko
Copy link

@AndrewKushnir We use FrameworkStabilizer to wait until Angular application finish rendering and available for interaction.
We know about Protractor deprecation and moved to native selenium-webdriver (all other alternatives like webdriver-io, cypress etc are not suitable for our needs).
Since selenium doesn't have built-in waits and explicit waits functionality not enough to make sure that page rendering completed - we taken example of angular-wait provided by Keen https://github.com/kyliau/angular-wait/blob/main/server/server.ts

and whether there are existing replacement APIs (provided by Angular) that you can consider?

We need some condition to check that all pending http requests and angular rendering finished so it guarantee that elements on page will not change. Is there any alternative API provided by Angular to execute js code in browser which say us that Angular fully rendered?
This very critical for our e2e infrastructure.

@AndrewKushnir
Copy link
Contributor Author

@StanislavKharchenko thanks for additional information.

We need some condition to check that all pending http requests and angular rendering finished so it guarantee that elements on page will not change. Is there any alternative API provided by Angular to execute js code in browser which say us that Angular fully rendered?

As a possible option you can use ApplicationRef.isStable (see more info here). You can obtain a reference to the ApplicationRef by either:

const ngModuleRef = platformBrowser().bootstapModule(YourAppModule);
const appRef = ngModuleRef.injector.get(ApplicatonRef);
// the `appRef.isStable` is available here.

or directly from the bootstrapApplication call:

const appRef = bootstrapApplication(YourRootBootstrapComponent);
// the `appRef.isStable` is available here.

Similar approach is used for the SSR use-cases (see here).

Please let me know if that would work for your use-case.

Thank you.

@StanislavKharchenko
Copy link

StanislavKharchenko commented May 13, 2022

const ngModuleRef = platformBrowser().bootstapModule(YourAppModule);
const appRef = ngModuleRef.injector.get(ApplicatonRef);
// the appRef.isStable is available here.

@AndrewKushnir It seems this solution is suitable in case if e2e tests are under application structure.
For our cases we have independent e2e infrastructure that lives outside Angular application folder.
So we need something that provided by Angular to execute in browser and get results which say that application stable.
For now - these are "getAngularTestabilities" (or "frameworkstabilizers") from global window object.

Could "ApplicationRef" be accessible from browser not in dev. mode?

@AndrewKushnir
Copy link
Contributor Author

@StanislavKharchenko I think you can try exposing the ApplicationRef.isStable on the window and get an access to that reference in your e2e test code, so it'd be very close to what you get with Testability classes:

// in your Angular app code:
const appRef = bootstrapApplication(YourRootBootstrapComponent);
window.isAngularAppStable = appRef.isStable;

// later in the e2e code:
window.isAngularAppStable.subscribe( ... );

@StanislavKharchenko
Copy link

@AndrewKushnir So it looks like relevant with v14 release when "bootstrapApplication" will be available.
Thanks.

@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 Jun 15, 2022
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 core: performance cross-cutting: standalone Issues related to the NgModule-less world target: rc This PR is targeted for the next release-candidate
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants