-
Notifications
You must be signed in to change notification settings - Fork 2.3k
NgUpgrade init breaks when run through Protractor #4327
Comments
Thanks for the detailed description and repo. I'm 90% sure the problem is where upgradeModule patches resumeBootstrap. Protractor expects this to return a reference to the injector, which it then assigns to window.$injector. The patched version return null, since it needs to be async. Protractor needs a new way to get ahold of the injector. I'm not sure I understand why apps are looking for window.$injector though. What if there are multiple Angular apps on a page? Also, in this upgrade app are you using the AngularJS or the Angular version of ui-router? From within Angular code, the right way to get the AngularJS injector is with Angular's dependency injection. I don't have a great example on hand, but something like this: // ng.auto.IInjectorService is from the AngularJS typings
export function getOldService(i: ng.auto.IInjectorService) {
// i is a reference to $injector from AngularJS
return i.get('oldAngularJSServie');
}
@NgModule({
providers: [{
provide: OldService,
useFactory: getOldService,
deps: ['$injector']
}],
})
export class oldServiceModule {
} |
OK, after a lot more debugging, I don't think this is a Protractor issue. It is a general problem with using the Upgrade module and deferred bootstrapping, which UI Router is triggering when run through Protractor. The problem is that, when bootstrapping a hybrid app normally, The solution is to ensure that any Angular component or service that expects Fun. |
I'd just like to comment here since this is the most relevant information I found. You cannot use upgraded AngularJS services (and probably components) in an Angular component that is also in the We were writing an Angular component that we needed to downgrade and use in AngularJS, and we also had our Our
|
The Angular static NgUpgrade module contains code to provide the AngularJS
$injector
service to Angular. The ui-router library relies on this to get access to AngularJS dependencies from an Angular context. When a hybrid app is run through Protractor, this breaks, and$injector
is not available in an Angular context.The code responsible for providing
$injector
to Angular is in upgrade_module.ts. The upgrade adds a new AngularJS module that stashes the$injector
instance in a local var, which it then provides to Angular whenUpgradeModule
is imported into a hybrid app.For some reason, it seems that when an app is running under Protractor, the upgrade AngularJS module code is not called, which means the copy of
$injector
it later provides to Angular is undefined.I have slightly modified the test app from the Protractor source tree to demonstrate the problem:
https://github.com/jonrimmer/protractor-ngupgrade-bug
I have added some code to the
update/app/main.ts
to populatewindow.$injector
with whatever the Angular injector has stored for'$injector'
when the app has finished bootstrapping.If the example is opened through a normal browser, it can be confirmed that
window.$injector
is populated with the$injector
instance.However, when the test contained in
spec.js
is run through Protractor, the value ofwindow.$injector
is null.v7.90
5.1.2
1.6
and `4Tested in Chrome and Firefox
macOS 10.12.5
The text was updated successfully, but these errors were encountered: