-
Notifications
You must be signed in to change notification settings - Fork 26.6k
docs: add tests for lazy loading AngularJS example #30622
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import { browser, element, by, ExpectedConditions } from 'protractor'; | ||
|
||
describe('Lazy Loading AngularJS Tests', function () { | ||
const pageElements = { | ||
homePageHref: element(by.cssContainingText('app-root nav a', 'Home')), | ||
homePageParagraph: element(by.css('app-root app-home p')), | ||
ajsUsersPageHref: element(by.cssContainingText('app-root nav a', 'Users')), | ||
ajsUsersPageParagraph: element(by.css('app-root app-angular-js div p')), | ||
notFoundPageHref: element(by.cssContainingText('app-root nav a', '404 Page')), | ||
notFoundPageParagraph: element(by.css('app-root app-app404 p')), | ||
}; | ||
|
||
beforeAll(async() => { | ||
await browser.get('/'); | ||
}); | ||
|
||
it('should display \'Angular Home\' when visiting the home page', async() => { | ||
await pageElements.homePageHref.click(); | ||
|
||
const paragraphText = await pageElements.homePageParagraph.getText(); | ||
|
||
expect(paragraphText).toEqual('Angular Home'); | ||
}); | ||
|
||
it('should display \'Users Page\' page when visiting the AngularJS page at /users', async() => { | ||
await pageElements.ajsUsersPageHref.click(); | ||
await loadAngularJS(); | ||
|
||
const paragraphText = await pageElements.ajsUsersPageParagraph.getText(); | ||
|
||
expect(paragraphText).toEqual('Users Page'); | ||
}); | ||
|
||
it('should display \'Angular 404\' when visiting an invalid URL', async() => { | ||
await pageElements.notFoundPageHref.click(); | ||
|
||
const paragraphText = await pageElements.notFoundPageParagraph.getText(); | ||
|
||
expect(paragraphText).toEqual('Angular 404'); | ||
}); | ||
|
||
// Workaround for https://github.com/angular/protractor/issues/4724 | ||
async function loadAngularJS() { | ||
// Abort if `resumeBootstrap` has already occured | ||
if (await browser.executeScript(`return '__TESTABILITY__NG1_APP_ROOT_INJECTOR__' in window;`)) { | ||
return; | ||
} | ||
|
||
// Might have to re-insert the 'NG_DEFER_BOOTSTRAP!' if the name has been changed since protractor loaded the page | ||
if (!await browser.executeScript('window.name.includes(\'NG_DEFER_BOOTSTRAP!\')')) { | ||
await browser.executeScript('window.name = \'NG_DEFER_BOOTSTRAP!\' + name'); | ||
} | ||
|
||
// Wait for the AngularJS bundle to download and initialize | ||
await browser.wait(ExpectedConditions.presenceOf(element(by.css('app-root app-angular-js'))), 5000, 'AngularJS app'); | ||
|
||
// Run the protractor pre-bootstrap logic and resumeBootstrap | ||
// Based on https://github.com/angular/protractor/blob/5.3.0/lib/browser.ts#L950-L969 | ||
{ | ||
let moduleNames = []; | ||
for (const {name, script, args} of browser.mockModules_) { | ||
moduleNames.push(name); | ||
await browser.executeScriptWithDescription(script, 'add mock module ' + name, ...args); | ||
} | ||
|
||
await browser.executeScriptWithDescription( | ||
// TODO: must manually assign __TESTABILITY__NG1_APP_ROOT_INJECTOR__ (https://github.com/angular/angular/issues/22723) | ||
`window.__TESTABILITY__NG1_APP_ROOT_INJECTOR__ = angular.resumeBootstrap(arguments[0]) ` | ||
+ `|| angular.element('app-angular-js').injector();`, | ||
'resume bootstrap', | ||
moduleNames | ||
); | ||
} | ||
|
||
// Wait for the initial AngularJS page to finish loading | ||
await browser.waitForAngular(); | ||
} | ||
}); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"projectType": "cli-ajs" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,22 @@ | ||
import { Component, OnInit, ElementRef } from '@angular/core'; | ||
import { Component, OnInit, OnDestroy, ElementRef } from '@angular/core'; | ||
import { LazyLoaderService } from '../lazy-loader.service'; | ||
|
||
@Component({ | ||
selector: 'app-angular-js', | ||
template: '<div ng-view></div>' | ||
}) | ||
export class AngularJSComponent implements OnInit { | ||
constructor(private lazyLoader: LazyLoaderService, private elRef: ElementRef) {} | ||
export class AngularJSComponent implements OnInit, OnDestroy { | ||
constructor( | ||
private lazyLoader: LazyLoaderService, | ||
private elRef: ElementRef | ||
) {} | ||
|
||
ngOnInit() { | ||
this.lazyLoader.load(this.elRef.nativeElement); | ||
} | ||
|
||
|
||
ngOnDestroy() { | ||
this.lazyLoader.destroy(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,25 @@ | ||
import { Injectable } from '@angular/core'; | ||
import * as angular from 'angular'; | ||
|
||
@Injectable({ | ||
providedIn: 'root' | ||
}) | ||
export class LazyLoaderService { | ||
bootstrapped = false; | ||
private app: angular.auto.IInjectorService; | ||
|
||
load(el: HTMLElement): void { | ||
if (this.bootstrapped) { | ||
return; | ||
} | ||
|
||
import('./angularjs-app').then(app => { | ||
try { | ||
app.bootstrap(el); | ||
this.bootstrapped = true; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why these changes? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The router destroys the component that holds the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That is definitely NOT recommended by me 😁 a. Depending on how you do the bundling, you may end up loading and running the same code repeatedly (and unnecessarily). Let's discuss this offline. |
||
this.app = app.bootstrap(el); | ||
} catch (e) { | ||
console.error(e); | ||
} | ||
}); | ||
} | ||
|
||
destroy() { | ||
if (this.app) { | ||
this.app.get('$rootScope').$destroy(); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
{ | ||
"scripts": [ | ||
{ "name": "ng", "command": "ng" }, | ||
{ "name": "build", "command": "ng build --prod" }, | ||
{ "name": "start", "command": "ng serve" }, | ||
{ "name": "test", "command": "ng test" }, | ||
{ "name": "lint", "command": "ng lint" }, | ||
{ "name": "e2e", "command": "ng e2e" } | ||
], | ||
"dependencies": [ | ||
"angular", | ||
"angular-route" | ||
], | ||
"devDependencies": [ | ||
"@angular/cli", | ||
"@types/angular", | ||
"@types/angular-route", | ||
"@types/jasminewd2", | ||
"jasmine-spec-reporter", | ||
"karma-coverage-istanbul-reporter", | ||
"ts-node" | ||
] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
{ | ||
brandonroberts marked this conversation as resolved.
Show resolved
Hide resolved
|
||
"name": "angular.io-example", | ||
"version": "0.0.0", | ||
"license": "MIT", | ||
"scripts": { | ||
"ng": "ng", | ||
"start": "ng serve", | ||
"build": "ng build", | ||
"test": "ng test", | ||
"lint": "ng lint", | ||
"e2e": "ng e2e" | ||
}, | ||
"private": true, | ||
"dependencies": { | ||
"@angular/animations": "^8.0.0", | ||
"@angular/common": "^8.0.0", | ||
"@angular/compiler": "^8.0.0", | ||
"@angular/core": "^8.0.0", | ||
"@angular/forms": "^8.0.0", | ||
"@angular/platform-browser": "^8.0.0", | ||
"@angular/platform-browser-dynamic": "^8.0.0", | ||
"@angular/router": "^8.0.0", | ||
"angular": "1.7.8", | ||
"angular-in-memory-web-api": "^0.8.0", | ||
"angular-route": "1.7.8", | ||
"core-js": "^2.5.4", | ||
"rxjs": "^6.5.1", | ||
"tslib": "^1.9.0", | ||
"web-animations-js": "^2.3.1", | ||
"zone.js": "~0.9.1" | ||
}, | ||
"devDependencies": { | ||
"@angular-devkit/build-angular": "^0.800.0", | ||
"@angular/cli": "^8.0.0", | ||
"@angular/compiler-cli": "^8.0.0", | ||
"@angular/language-service": "^8.0.0", | ||
"@types/angular": "^1.6.47", | ||
"@types/angular-route": "^1.3.5", | ||
"@types/jasmine": "~3.3.8", | ||
"@types/jasminewd2": "~2.0.3", | ||
"@types/node": "~8.9.4", | ||
"codelyzer": "~5.0.0", | ||
"jasmine-core": "~2.99.1", | ||
"jasmine-marbles": "^0.5.0", | ||
"jasmine-spec-reporter": "~4.2.1", | ||
"karma": "~4.1.0", | ||
"karma-chrome-launcher": "~2.2.0", | ||
"karma-coverage-istanbul-reporter": "~2.0.1", | ||
"karma-jasmine": "~2.0.1", | ||
"karma-jasmine-html-reporter": "^0.2.2", | ||
"protractor": "~5.4.0", | ||
"ts-node": "~7.0.0", | ||
"tslint": "~5.15.0", | ||
"typescript": "~3.4.4" | ||
} | ||
} |
Uh oh!
There was an error while loading. Please reload this page.