| 
									
										
										
										
											2017-03-07 17:27:20 -05:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @license | 
					
						
							| 
									
										
										
										
											2020-05-19 12:08:49 -07:00
										 |  |  |  * Copyright Google LLC All Rights Reserved. | 
					
						
							| 
									
										
										
										
											2017-03-07 17:27:20 -05:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Use of this source code is governed by an MIT-style license that can be | 
					
						
							|  |  |  |  * found in the LICENSE file at https://angular.io/license
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-16 14:42:22 +02:00
										 |  |  | import {APP_BASE_HREF, DOCUMENT, ɵgetDOM as getDOM} from '@angular/common'; | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  | import {ApplicationRef, Component, CUSTOM_ELEMENTS_SCHEMA, destroyPlatform, NgModule} from '@angular/core'; | 
					
						
							| 
									
										
										
										
											2017-03-07 17:27:20 -05:00
										 |  |  | import {inject} from '@angular/core/testing'; | 
					
						
							| 
									
										
										
										
											2019-08-22 19:16:25 -07:00
										 |  |  | import {BrowserModule} from '@angular/platform-browser'; | 
					
						
							| 
									
										
										
										
											2017-03-07 17:27:20 -05:00
										 |  |  | import {platformBrowserDynamic} from '@angular/platform-browser-dynamic'; | 
					
						
							| 
									
										
										
										
											2019-03-11 19:20:40 -05:00
										 |  |  | import {NavigationEnd, Resolve, Router, RouterModule} from '@angular/router'; | 
					
						
							| 
									
										
										
										
											2017-03-07 17:27:20 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | describe('bootstrap', () => { | 
					
						
							| 
									
										
										
										
											2017-12-17 20:59:37 -08:00
										 |  |  |   if (isNode) return; | 
					
						
							| 
									
										
										
										
											2017-03-07 17:27:20 -05:00
										 |  |  |   let log: any[] = []; | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |   let testProviders: any[] = null!; | 
					
						
							| 
									
										
										
										
											2017-03-07 17:27:20 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-03-18 09:10:22 -07:00
										 |  |  |   @Component({template: 'simple'}) | 
					
						
							|  |  |  |   class SimpleCmp { | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-07 17:27:20 -05:00
										 |  |  |   @Component({selector: 'test-app', template: 'root <router-outlet></router-outlet>'}) | 
					
						
							|  |  |  |   class RootCmp { | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |     constructor() { | 
					
						
							|  |  |  |       log.push('RootCmp'); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-03-07 17:27:20 -05:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   @Component({selector: 'test-app2', template: 'root <router-outlet></router-outlet>'}) | 
					
						
							|  |  |  |   class SecondRootCmp { | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   class TestResolver implements Resolve<any> { | 
					
						
							|  |  |  |     resolve() { | 
					
						
							|  |  |  |       let resolve: any = null; | 
					
						
							|  |  |  |       const res = new Promise(r => resolve = r); | 
					
						
							|  |  |  |       setTimeout(() => resolve('test-data'), 0); | 
					
						
							|  |  |  |       return res; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   beforeEach(inject([DOCUMENT], (doc: any) => { | 
					
						
							|  |  |  |     destroyPlatform(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const el1 = getDOM().createElement('test-app', doc); | 
					
						
							|  |  |  |     const el2 = getDOM().createElement('test-app2', doc); | 
					
						
							| 
									
										
										
										
											2019-08-30 12:52:48 -07:00
										 |  |  |     doc.body.appendChild(el1); | 
					
						
							|  |  |  |     doc.body.appendChild(el2); | 
					
						
							| 
									
										
										
										
											2017-03-07 17:27:20 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     log = []; | 
					
						
							|  |  |  |     testProviders = [{provide: APP_BASE_HREF, useValue: ''}]; | 
					
						
							|  |  |  |   })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   afterEach(inject([DOCUMENT], (doc: any) => { | 
					
						
							| 
									
										
										
										
											2019-08-30 12:52:48 -07:00
										 |  |  |     const oldRoots = doc.querySelectorAll('test-app,test-app2'); | 
					
						
							| 
									
										
										
										
											2017-03-07 17:27:20 -05:00
										 |  |  |     for (let i = 0; i < oldRoots.length; i++) { | 
					
						
							|  |  |  |       getDOM().remove(oldRoots[i]); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should wait for resolvers to complete when initialNavigation = enabled', (done) => { | 
					
						
							|  |  |  |     @Component({selector: 'test', template: 'test'}) | 
					
						
							|  |  |  |     class TestCmpEnabled { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @NgModule({ | 
					
						
							|  |  |  |       imports: [ | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |         BrowserModule, | 
					
						
							|  |  |  |         RouterModule.forRoot( | 
					
						
							|  |  |  |             [{path: '**', component: TestCmpEnabled, resolve: {test: TestResolver}}], | 
					
						
							|  |  |  |             {useHash: true, initialNavigation: 'enabled'}) | 
					
						
							| 
									
										
										
										
											2017-03-07 17:27:20 -05:00
										 |  |  |       ], | 
					
						
							|  |  |  |       declarations: [RootCmp, TestCmpEnabled], | 
					
						
							|  |  |  |       bootstrap: [RootCmp], | 
					
						
							|  |  |  |       providers: [...testProviders, TestResolver], | 
					
						
							|  |  |  |       schemas: [CUSTOM_ELEMENTS_SCHEMA] | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  |     class TestModule { | 
					
						
							|  |  |  |       constructor(router: Router) { | 
					
						
							|  |  |  |         log.push('TestModule'); | 
					
						
							|  |  |  |         router.events.subscribe(e => log.push(e.constructor.name)); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     platformBrowserDynamic([]).bootstrapModule(TestModule).then(res => { | 
					
						
							|  |  |  |       const router = res.injector.get(Router); | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |       const data = router.routerState.snapshot.root.firstChild!.data; | 
					
						
							| 
									
										
										
										
											2017-03-07 17:27:20 -05:00
										 |  |  |       expect(data['test']).toEqual('test-data'); | 
					
						
							| 
									
										
										
										
											2017-07-01 10:30:17 -07:00
										 |  |  |       expect(log).toEqual([ | 
					
						
							| 
									
										
										
										
											2017-09-04 13:00:59 -07:00
										 |  |  |         'TestModule', 'NavigationStart', 'RoutesRecognized', 'GuardsCheckStart', | 
					
						
							| 
									
										
										
										
											2017-09-06 11:00:32 -07:00
										 |  |  |         'ChildActivationStart', 'ActivationStart', 'GuardsCheckEnd', 'ResolveStart', 'ResolveEnd', | 
					
						
							| 
									
										
										
										
											2018-05-17 07:33:50 -04:00
										 |  |  |         'RootCmp', 'ActivationEnd', 'ChildActivationEnd', 'NavigationEnd', 'Scroll' | 
					
						
							| 
									
										
										
										
											2017-07-01 10:30:17 -07:00
										 |  |  |       ]); | 
					
						
							| 
									
										
										
										
											2017-03-07 17:27:20 -05:00
										 |  |  |       done(); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-07 18:01:11 -05:00
										 |  |  |   it('should wait for resolvers to complete when initialNavigation = enabledBlocking', (done) => { | 
					
						
							|  |  |  |     @Component({selector: 'test', template: 'test'}) | 
					
						
							|  |  |  |     class TestCmpEnabled { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @NgModule({ | 
					
						
							|  |  |  |       imports: [ | 
					
						
							|  |  |  |         BrowserModule, | 
					
						
							|  |  |  |         RouterModule.forRoot( | 
					
						
							|  |  |  |             [{path: '**', component: TestCmpEnabled, resolve: {test: TestResolver}}], | 
					
						
							|  |  |  |             {useHash: true, initialNavigation: 'enabledBlocking'}) | 
					
						
							|  |  |  |       ], | 
					
						
							|  |  |  |       declarations: [RootCmp, TestCmpEnabled], | 
					
						
							|  |  |  |       bootstrap: [RootCmp], | 
					
						
							|  |  |  |       providers: [...testProviders, TestResolver], | 
					
						
							|  |  |  |       schemas: [CUSTOM_ELEMENTS_SCHEMA] | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  |     class TestModule { | 
					
						
							|  |  |  |       constructor(router: Router) { | 
					
						
							|  |  |  |         log.push('TestModule'); | 
					
						
							|  |  |  |         router.events.subscribe(e => log.push(e.constructor.name)); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     platformBrowserDynamic([]).bootstrapModule(TestModule).then(res => { | 
					
						
							|  |  |  |       const router = res.injector.get(Router); | 
					
						
							|  |  |  |       const data = router.routerState.snapshot.root.firstChild!.data; | 
					
						
							|  |  |  |       expect(data['test']).toEqual('test-data'); | 
					
						
							|  |  |  |       expect(log).toEqual([ | 
					
						
							|  |  |  |         'TestModule', 'NavigationStart', 'RoutesRecognized', 'GuardsCheckStart', | 
					
						
							|  |  |  |         'ChildActivationStart', 'ActivationStart', 'GuardsCheckEnd', 'ResolveStart', 'ResolveEnd', | 
					
						
							|  |  |  |         'RootCmp', 'ActivationEnd', 'ChildActivationEnd', 'NavigationEnd', 'Scroll' | 
					
						
							|  |  |  |       ]); | 
					
						
							|  |  |  |       done(); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should NOT wait for resolvers to complete when initialNavigation = enabledNonBlocking', | 
					
						
							| 
									
										
										
										
											2017-08-22 18:39:06 -05:00
										 |  |  |      (done) => { | 
					
						
							|  |  |  |        @Component({selector: 'test', template: 'test'}) | 
					
						
							|  |  |  |        class TestCmpLegacyEnabled { | 
					
						
							|  |  |  |        } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        @NgModule({ | 
					
						
							|  |  |  |          imports: [ | 
					
						
							|  |  |  |            BrowserModule, | 
					
						
							|  |  |  |            RouterModule.forRoot( | 
					
						
							|  |  |  |                [{path: '**', component: TestCmpLegacyEnabled, resolve: {test: TestResolver}}], | 
					
						
							| 
									
										
										
										
											2020-06-07 18:01:11 -05:00
										 |  |  |                {useHash: true, initialNavigation: 'enabledNonBlocking'}) | 
					
						
							| 
									
										
										
										
											2017-08-22 18:39:06 -05:00
										 |  |  |          ], | 
					
						
							|  |  |  |          declarations: [RootCmp, TestCmpLegacyEnabled], | 
					
						
							|  |  |  |          bootstrap: [RootCmp], | 
					
						
							|  |  |  |          providers: [...testProviders, TestResolver], | 
					
						
							|  |  |  |          schemas: [CUSTOM_ELEMENTS_SCHEMA] | 
					
						
							|  |  |  |        }) | 
					
						
							|  |  |  |        class TestModule { | 
					
						
							|  |  |  |          constructor(router: Router) { | 
					
						
							|  |  |  |            log.push('TestModule'); | 
					
						
							|  |  |  |            router.events.subscribe(e => log.push(e.constructor.name)); | 
					
						
							|  |  |  |          } | 
					
						
							|  |  |  |        } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        platformBrowserDynamic([]).bootstrapModule(TestModule).then(res => { | 
					
						
							| 
									
										
										
										
											2019-06-14 12:19:09 +02:00
										 |  |  |          const router: Router = res.injector.get(Router); | 
					
						
							| 
									
										
										
										
											2017-08-22 18:39:06 -05:00
										 |  |  |          expect(router.routerState.snapshot.root.firstChild).toBeNull(); | 
					
						
							|  |  |  |          // ResolveEnd has not been emitted yet because bootstrap returned too early
 | 
					
						
							|  |  |  |          expect(log).toEqual([ | 
					
						
							|  |  |  |            'TestModule', 'RootCmp', 'NavigationStart', 'RoutesRecognized', 'GuardsCheckStart', | 
					
						
							| 
									
										
										
										
											2017-09-06 11:00:32 -07:00
										 |  |  |            'ChildActivationStart', 'ActivationStart', 'GuardsCheckEnd', 'ResolveStart' | 
					
						
							| 
									
										
										
										
											2017-08-22 18:39:06 -05:00
										 |  |  |          ]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |          router.events.subscribe((e) => { | 
					
						
							|  |  |  |            if (e instanceof NavigationEnd) { | 
					
						
							|  |  |  |              done(); | 
					
						
							|  |  |  |            } | 
					
						
							|  |  |  |          }); | 
					
						
							|  |  |  |        }); | 
					
						
							|  |  |  |      }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-07 18:01:11 -05:00
										 |  |  |   it('should NOT wait for resolvers to complete when initialNavigation is not set', (done) => { | 
					
						
							| 
									
										
										
										
											2017-03-07 17:27:20 -05:00
										 |  |  |     @Component({selector: 'test', template: 'test'}) | 
					
						
							| 
									
										
										
										
											2020-06-07 18:01:11 -05:00
										 |  |  |     class TestCmpLegacyEnabled { | 
					
						
							| 
									
										
										
										
											2017-03-07 17:27:20 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @NgModule({ | 
					
						
							|  |  |  |       imports: [ | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |         BrowserModule, | 
					
						
							|  |  |  |         RouterModule.forRoot( | 
					
						
							| 
									
										
										
										
											2020-06-07 18:01:11 -05:00
										 |  |  |             [{path: '**', component: TestCmpLegacyEnabled, resolve: {test: TestResolver}}], | 
					
						
							|  |  |  |             {useHash: true}) | 
					
						
							| 
									
										
										
										
											2017-03-07 17:27:20 -05:00
										 |  |  |       ], | 
					
						
							| 
									
										
										
										
											2020-06-07 18:01:11 -05:00
										 |  |  |       declarations: [RootCmp, TestCmpLegacyEnabled], | 
					
						
							| 
									
										
										
										
											2017-03-07 17:27:20 -05:00
										 |  |  |       bootstrap: [RootCmp], | 
					
						
							|  |  |  |       providers: [...testProviders, TestResolver], | 
					
						
							|  |  |  |       schemas: [CUSTOM_ELEMENTS_SCHEMA] | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  |     class TestModule { | 
					
						
							|  |  |  |       constructor(router: Router) { | 
					
						
							|  |  |  |         log.push('TestModule'); | 
					
						
							|  |  |  |         router.events.subscribe(e => log.push(e.constructor.name)); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     platformBrowserDynamic([]).bootstrapModule(TestModule).then(res => { | 
					
						
							| 
									
										
										
										
											2020-06-07 18:01:11 -05:00
										 |  |  |       const router: Router = res.injector.get(Router); | 
					
						
							|  |  |  |       expect(router.routerState.snapshot.root.firstChild).toBeNull(); | 
					
						
							|  |  |  |       // ResolveEnd has not been emitted yet because bootstrap returned too early
 | 
					
						
							|  |  |  |       expect(log).toEqual([ | 
					
						
							|  |  |  |         'TestModule', 'RootCmp', 'NavigationStart', 'RoutesRecognized', 'GuardsCheckStart', | 
					
						
							|  |  |  |         'ChildActivationStart', 'ActivationStart', 'GuardsCheckEnd', 'ResolveStart' | 
					
						
							|  |  |  |       ]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       router.events.subscribe((e) => { | 
					
						
							|  |  |  |         if (e instanceof NavigationEnd) { | 
					
						
							|  |  |  |           done(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2017-08-22 18:39:06 -05:00
										 |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-07 18:01:11 -05:00
										 |  |  |   it('should not run navigation when initialNavigation = disabled', (done) => { | 
					
						
							| 
									
										
										
										
											2017-08-22 18:39:06 -05:00
										 |  |  |     @Component({selector: 'test', template: 'test'}) | 
					
						
							| 
									
										
										
										
											2020-06-07 18:01:11 -05:00
										 |  |  |     class TestCmpDiabled { | 
					
						
							| 
									
										
										
										
											2017-08-22 18:39:06 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @NgModule({ | 
					
						
							|  |  |  |       imports: [ | 
					
						
							|  |  |  |         BrowserModule, | 
					
						
							|  |  |  |         RouterModule.forRoot( | 
					
						
							| 
									
										
										
										
											2020-06-07 18:01:11 -05:00
										 |  |  |             [{path: '**', component: TestCmpDiabled, resolve: {test: TestResolver}}], | 
					
						
							|  |  |  |             {useHash: true, initialNavigation: 'disabled'}) | 
					
						
							| 
									
										
										
										
											2017-08-22 18:39:06 -05:00
										 |  |  |       ], | 
					
						
							| 
									
										
										
										
											2020-06-07 18:01:11 -05:00
										 |  |  |       declarations: [RootCmp, TestCmpDiabled], | 
					
						
							| 
									
										
										
										
											2017-08-22 18:39:06 -05:00
										 |  |  |       bootstrap: [RootCmp], | 
					
						
							|  |  |  |       providers: [...testProviders, TestResolver], | 
					
						
							|  |  |  |       schemas: [CUSTOM_ELEMENTS_SCHEMA] | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  |     class TestModule { | 
					
						
							|  |  |  |       constructor(router: Router) { | 
					
						
							|  |  |  |         log.push('TestModule'); | 
					
						
							|  |  |  |         router.events.subscribe(e => log.push(e.constructor.name)); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     platformBrowserDynamic([]).bootstrapModule(TestModule).then(res => { | 
					
						
							| 
									
										
										
										
											2017-03-07 17:27:20 -05:00
										 |  |  |       const router = res.injector.get(Router); | 
					
						
							|  |  |  |       expect(log).toEqual(['TestModule', 'RootCmp']); | 
					
						
							|  |  |  |       done(); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should not init router navigation listeners if a non root component is bootstrapped', | 
					
						
							|  |  |  |      (done) => { | 
					
						
							|  |  |  |        @NgModule({ | 
					
						
							|  |  |  |          imports: [BrowserModule, RouterModule.forRoot([], {useHash: true})], | 
					
						
							|  |  |  |          declarations: [SecondRootCmp, RootCmp], | 
					
						
							|  |  |  |          entryComponents: [SecondRootCmp], | 
					
						
							|  |  |  |          bootstrap: [RootCmp], | 
					
						
							|  |  |  |          providers: testProviders, | 
					
						
							|  |  |  |          schemas: [CUSTOM_ELEMENTS_SCHEMA] | 
					
						
							|  |  |  |        }) | 
					
						
							|  |  |  |        class TestModule { | 
					
						
							|  |  |  |        } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        platformBrowserDynamic([]).bootstrapModule(TestModule).then(res => { | 
					
						
							|  |  |  |          const router = res.injector.get(Router); | 
					
						
							| 
									
										
										
										
											2017-10-24 14:54:08 +03:00
										 |  |  |          spyOn(router as any, 'resetRootComponentType').and.callThrough(); | 
					
						
							| 
									
										
										
										
											2017-03-07 17:27:20 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |          const appRef: ApplicationRef = res.injector.get(ApplicationRef); | 
					
						
							|  |  |  |          appRef.bootstrap(SecondRootCmp); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-17 15:10:54 -08:00
										 |  |  |          expect((router as any).resetRootComponentType).not.toHaveBeenCalled(); | 
					
						
							| 
									
										
										
										
											2017-03-07 17:27:20 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |          done(); | 
					
						
							|  |  |  |        }); | 
					
						
							|  |  |  |      }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should reinit router navigation listeners if a previously bootstrapped root component is destroyed', | 
					
						
							|  |  |  |      (done) => { | 
					
						
							|  |  |  |        @NgModule({ | 
					
						
							|  |  |  |          imports: [BrowserModule, RouterModule.forRoot([], {useHash: true})], | 
					
						
							|  |  |  |          declarations: [SecondRootCmp, RootCmp], | 
					
						
							|  |  |  |          entryComponents: [SecondRootCmp], | 
					
						
							|  |  |  |          bootstrap: [RootCmp], | 
					
						
							|  |  |  |          providers: testProviders, | 
					
						
							|  |  |  |          schemas: [CUSTOM_ELEMENTS_SCHEMA] | 
					
						
							|  |  |  |        }) | 
					
						
							|  |  |  |        class TestModule { | 
					
						
							|  |  |  |        } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        platformBrowserDynamic([]).bootstrapModule(TestModule).then(res => { | 
					
						
							|  |  |  |          const router = res.injector.get(Router); | 
					
						
							| 
									
										
										
										
											2017-10-24 14:54:08 +03:00
										 |  |  |          spyOn(router as any, 'resetRootComponentType').and.callThrough(); | 
					
						
							| 
									
										
										
										
											2017-03-07 17:27:20 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |          const appRef: ApplicationRef = res.injector.get(ApplicationRef); | 
					
						
							|  |  |  |          appRef.components[0].onDestroy(() => { | 
					
						
							|  |  |  |            appRef.bootstrap(SecondRootCmp); | 
					
						
							| 
									
										
										
										
											2017-12-17 15:10:54 -08:00
										 |  |  |            expect((router as any).resetRootComponentType).toHaveBeenCalled(); | 
					
						
							| 
									
										
										
										
											2017-03-07 17:27:20 -05:00
										 |  |  |            done(); | 
					
						
							|  |  |  |          }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |          appRef.components[0].destroy(); | 
					
						
							|  |  |  |        }); | 
					
						
							|  |  |  |      }); | 
					
						
							| 
									
										
										
										
											2018-05-17 07:33:50 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-13 16:40:21 -07:00
										 |  |  |   it('should restore the scrolling position', async (done) => { | 
					
						
							| 
									
										
										
										
											2018-05-17 07:33:50 -04:00
										 |  |  |     @Component({ | 
					
						
							|  |  |  |       selector: 'component-a', | 
					
						
							|  |  |  |       template: `
 | 
					
						
							|  |  |  |            <div style="height: 3000px;"></div> | 
					
						
							|  |  |  |            <div id="marker1"></div> | 
					
						
							|  |  |  |            <div style="height: 3000px;"></div> | 
					
						
							|  |  |  |            <div id="marker2"></div> | 
					
						
							|  |  |  |            <div style="height: 3000px;"></div> | 
					
						
							|  |  |  |            <a name="marker3"></a> | 
					
						
							|  |  |  |            <div style="height: 3000px;"></div> | 
					
						
							|  |  |  |       `
 | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  |     class TallComponent { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     @NgModule({ | 
					
						
							|  |  |  |       imports: [ | 
					
						
							|  |  |  |         BrowserModule, | 
					
						
							|  |  |  |         RouterModule.forRoot( | 
					
						
							|  |  |  |             [ | 
					
						
							|  |  |  |               {path: '', pathMatch: 'full', redirectTo: '/aa'}, | 
					
						
							|  |  |  |               {path: 'aa', component: TallComponent}, {path: 'bb', component: TallComponent}, | 
					
						
							|  |  |  |               {path: 'cc', component: TallComponent}, | 
					
						
							|  |  |  |               {path: 'fail', component: TallComponent, canActivate: ['returnFalse']} | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |               useHash: true, | 
					
						
							|  |  |  |               scrollPositionRestoration: 'enabled', | 
					
						
							|  |  |  |               anchorScrolling: 'enabled', | 
					
						
							|  |  |  |               scrollOffset: [0, 100], | 
					
						
							|  |  |  |               onSameUrlNavigation: 'reload' | 
					
						
							|  |  |  |             }) | 
					
						
							|  |  |  |       ], | 
					
						
							|  |  |  |       declarations: [TallComponent, RootCmp], | 
					
						
							|  |  |  |       bootstrap: [RootCmp], | 
					
						
							|  |  |  |       providers: [...testProviders, {provide: 'returnFalse', useValue: () => false}], | 
					
						
							|  |  |  |       schemas: [CUSTOM_ELEMENTS_SCHEMA] | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  |     class TestModule { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const res = await platformBrowserDynamic([]).bootstrapModule(TestModule); | 
					
						
							|  |  |  |     const router = res.injector.get(Router); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     await router.navigateByUrl('/aa'); | 
					
						
							|  |  |  |     window.scrollTo(0, 5000); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     await router.navigateByUrl('/fail'); | 
					
						
							| 
									
										
										
										
											2019-01-20 14:12:52 +01:00
										 |  |  |     expect(window.pageYOffset).toEqual(5000); | 
					
						
							| 
									
										
										
										
											2018-05-17 07:33:50 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     await router.navigateByUrl('/bb'); | 
					
						
							|  |  |  |     window.scrollTo(0, 3000); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-20 14:12:52 +01:00
										 |  |  |     expect(window.pageYOffset).toEqual(3000); | 
					
						
							| 
									
										
										
										
											2018-05-17 07:33:50 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     await router.navigateByUrl('/cc'); | 
					
						
							| 
									
										
										
										
											2019-01-20 14:12:52 +01:00
										 |  |  |     expect(window.pageYOffset).toEqual(0); | 
					
						
							| 
									
										
										
										
											2018-05-17 07:33:50 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     await router.navigateByUrl('/aa#marker2'); | 
					
						
							| 
									
										
										
										
											2019-01-20 14:12:52 +01:00
										 |  |  |     expect(window.pageYOffset).toBeGreaterThanOrEqual(5900); | 
					
						
							|  |  |  |     expect(window.pageYOffset).toBeLessThan(6000);  // offset
 | 
					
						
							| 
									
										
										
										
											2018-05-17 07:33:50 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     await router.navigateByUrl('/aa#marker3'); | 
					
						
							| 
									
										
										
										
											2019-01-20 14:12:52 +01:00
										 |  |  |     expect(window.pageYOffset).toBeGreaterThanOrEqual(8900); | 
					
						
							|  |  |  |     expect(window.pageYOffset).toBeLessThan(9000); | 
					
						
							| 
									
										
										
										
											2018-05-17 07:33:50 -04:00
										 |  |  |     done(); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-16 14:42:22 +02:00
										 |  |  |   it('should cleanup "popstate" and "hashchange" listeners', async () => { | 
					
						
							|  |  |  |     @NgModule({ | 
					
						
							|  |  |  |       imports: [BrowserModule, RouterModule.forRoot([])], | 
					
						
							|  |  |  |       declarations: [RootCmp], | 
					
						
							|  |  |  |       bootstrap: [RootCmp], | 
					
						
							|  |  |  |       providers: testProviders, | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  |     class TestModule { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     spyOn(window, 'addEventListener').and.callThrough(); | 
					
						
							|  |  |  |     spyOn(window, 'removeEventListener').and.callThrough(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const ngModuleRef = await platformBrowserDynamic().bootstrapModule(TestModule); | 
					
						
							|  |  |  |     ngModuleRef.destroy(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     expect(window.addEventListener).toHaveBeenCalledTimes(2); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     expect(window.addEventListener) | 
					
						
							|  |  |  |         .toHaveBeenCalledWith('popstate', jasmine.any(Function), jasmine.any(Boolean)); | 
					
						
							|  |  |  |     expect(window.addEventListener) | 
					
						
							|  |  |  |         .toHaveBeenCalledWith('hashchange', jasmine.any(Function), jasmine.any(Boolean)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     expect(window.removeEventListener).toHaveBeenCalledWith('popstate', jasmine.any(Function)); | 
					
						
							|  |  |  |     expect(window.removeEventListener).toHaveBeenCalledWith('hashchange', jasmine.any(Function)); | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2021-03-18 09:10:22 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   it('can schedule a navigation from the NavigationEnd event #37460', async (done) => { | 
					
						
							|  |  |  |     @NgModule({ | 
					
						
							|  |  |  |       imports: [ | 
					
						
							|  |  |  |         BrowserModule, | 
					
						
							|  |  |  |         RouterModule.forRoot( | 
					
						
							|  |  |  |             [ | 
					
						
							|  |  |  |               {path: 'a', component: SimpleCmp}, | 
					
						
							|  |  |  |               {path: 'b', component: SimpleCmp}, | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |       ], | 
					
						
							|  |  |  |       declarations: [RootCmp, SimpleCmp], | 
					
						
							|  |  |  |       bootstrap: [RootCmp], | 
					
						
							|  |  |  |       providers: [...testProviders], | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  |     class TestModule { | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const res = await platformBrowserDynamic([]).bootstrapModule(TestModule); | 
					
						
							|  |  |  |     const router = res.injector.get(Router); | 
					
						
							|  |  |  |     router.events.subscribe(() => { | 
					
						
							|  |  |  |       expect(router.getCurrentNavigation()?.id).toBeDefined(); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     router.events.subscribe(async (e) => { | 
					
						
							|  |  |  |       if (e instanceof NavigationEnd && e.url === '/b') { | 
					
						
							|  |  |  |         await router.navigate(['a']); | 
					
						
							|  |  |  |         done(); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     await router.navigateByUrl('/b'); | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2017-03-07 17:27:20 -05:00
										 |  |  | }); |