test(elements): add basic integration test for angular elements (#24861)

PR Close #24861
This commit is contained in:
Rob Wormald 2018-07-15 16:02:16 -07:00 committed by Misko Hevery
parent d76a7d6f7c
commit 4815b92495
14 changed files with 2735 additions and 11 deletions

View File

@ -0,0 +1,41 @@
--compilation_level=ADVANCED_OPTIMIZATIONS
--language_out=ES6
--language_in=ES6
--js_output_file=dist/bundle.js
--output_manifest=dist/manifest.MF
--variable_renaming_report=dist/variable_renaming_report
--property_renaming_report=dist/property_renaming_report
--create_source_map=%outname%.map
--warning_level=QUIET
--dependency_mode=STRICT
--rewrite_polyfills=false
--jscomp_off=checkVars
node_modules/zone.js/dist/zone_externs.js
--js node_modules/rxjs/package.json
--js node_modules/rxjs/_esm2015/index.js
--js node_modules/rxjs/_esm2015/internal/**.js
--js node_modules/rxjs/operators/package.json
--js node_modules/rxjs/_esm2015/operators/index.js
--js node_modules/@angular/core/package.json
--js node_modules/@angular/core/fesm2015/core.js
--js node_modules/@angular/core/src/testability/testability.externs.js
--js node_modules/@angular/common/package.json
--js node_modules/@angular/common/fesm2015/common.js
--js node_modules/@angular/platform-browser/package.json
--js node_modules/@angular/platform-browser/fesm2015/platform-browser.js
--js node_modules/@angular/elements/package.json
--js node_modules/@angular/elements/fesm2015/elements.js
--module_resolution=node
--package_json_entry_names es2015
--process_common_js_modules
--js built/**.js
--entry_point=built/src/main

View File

@ -0,0 +1,20 @@
import { browser, element, by } from 'protractor';
browser.waitForAngularEnabled(false);
describe('Element E2E Tests', function () {
describe('Hello World Elements', () => {
it('should display: Hello world!', function () {
browser.get('hello-world.html');
const helloWorldEl = element(by.css('hello-world-el'));
expect(helloWorldEl.getText()).toEqual('Hello World!');
});
it('should display: Hello fromIndex! via name attribute', function () {
browser.get('hello-world.html');
const helloWorldEl = element(by.css('hello-world-el'));
const input = element(by.css('input[type=text]'));
input.sendKeys('F', 'o', 'o');
expect(helloWorldEl.getText()).toEqual('Hello Foo!');
});
});
});

View File

@ -0,0 +1,15 @@
{
"open": false,
"logLevel": "silent",
"port": 8080,
"server": {
"baseDir": "src",
"routes": {
"/dist": "dist",
"/node_modules": "node_modules"
},
"middleware": {
"0": null
}
}
}

View File

@ -0,0 +1,16 @@
exports.config = {
specs: [
'../built/e2e/*.e2e-spec.js'
],
capabilities: {
browserName: 'chrome',
chromeOptions: {
args: ['--no-sandbox'],
binary: process.env.CHROME_BIN,
}
},
directConnect: true,
baseUrl: 'http://localhost:8080/',
framework: 'jasmine',
useAllAngular2AppRoots: true
};

View File

@ -0,0 +1,8 @@
{
"compilerOptions": {
"outDir": "../built/e2e",
"types": ["jasmine"],
// TODO(alexeagle): was required for Protractor 4.0.11
"skipLibCheck": true
}
}

View File

@ -0,0 +1,33 @@
{
"name": "angular-integration",
"version": "0.0.0",
"license": "MIT",
"dependencies": {
"@angular/animations": "file:../../dist/packages-dist/animations",
"@angular/common": "file:../../dist/packages-dist/common",
"@angular/compiler": "file:../../dist/packages-dist/compiler",
"@angular/compiler-cli": "file:../../dist/packages-dist/compiler-cli",
"@angular/core": "file:../../dist/packages-dist/core",
"@angular/elements": "file:../../dist/packages-dist/elements",
"@angular/platform-browser": "file:../../dist/packages-dist/platform-browser",
"@angular/platform-server": "file:../../dist/packages-dist/platform-server",
"google-closure-compiler": "20180319.0.0",
"rxjs": "file:../../node_modules/rxjs",
"typescript": "file:../../node_modules/typescript",
"zone.js": "file:../../node_modules/zone.js"
},
"devDependencies": {
"@types/jasmine": "2.5.41",
"concurrently": "3.4.0",
"lite-server": "2.2.2",
"protractor": "file:../../node_modules/protractor"
},
"scripts": {
"postinstall": "webdriver-manager update --gecko false --standalone false $CHROMEDRIVER_VERSION_ARG",
"closure": "java -jar node_modules/google-closure-compiler/compiler.jar --flagfile closure.conf",
"test": "ngc && yarn run closure && concurrently \"yarn run serve\" \"yarn run protractor\" --kill-others --success first",
"serve": "lite-server -c e2e/browser.config.json",
"preprotractor": "tsc -p e2e",
"protractor": "protractor e2e/protractor.config.js"
}
}

View File

@ -0,0 +1,33 @@
import {HelloWorldComponent, HelloWorldShadowComponent, TestCardComponent} from './elements';
import {NgModule, Injector} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {createCustomElement} from '@angular/elements';
@NgModule({
declarations: [HelloWorldComponent, HelloWorldShadowComponent, TestCardComponent],
entryComponents: [HelloWorldComponent, HelloWorldShadowComponent, TestCardComponent],
imports: [BrowserModule],
})
export class AppModule {
constructor(private injector:Injector){
customElements.define(
'hello-world-el',
createCustomElement(HelloWorldComponent, {injector})
);
customElements.define(
'hello-world-shadow-el',
createCustomElement(HelloWorldShadowComponent, {injector})
);
customElements.define(
'test-card',
createCustomElement(HelloWorldShadowComponent, {injector})
);
}
ngDoBootstrap(){
}
}
export {HelloWorldComponent};

View File

@ -0,0 +1,36 @@
import {Component, Input, ViewEncapsulation} from '@angular/core';
@Component({
selector: 'hello-world-el',
template: `Hello {{name}}!`,
})
export class HelloWorldComponent {
@Input() name: string = 'World';
}
@Component({
selector: 'hello-world-shadow-el',
template: `Hello {{name}}!`,
encapsulation: ViewEncapsulation.ShadowDom
})
export class HelloWorldShadowComponent {
@Input() name: string = 'World';
}
@Component({
selector: 'test-card',
template: `
<header>
<slot name="card-header"></slot>
</header>
<slot></slot>
<footer>
<slot name="card-footer"></slot>
</footer>`,
encapsulation: ViewEncapsulation.ShadowDom,
styles: []
})
export class TestCardComponent {
}

View File

@ -0,0 +1,17 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Hello World</title>
<base href="/">
</head>
<body>
<input type="text">
<hello-world-el></hello-world-el>
<script src="dist/bundle.js"></script>
</body>
</html>

View File

@ -0,0 +1,13 @@
import {platformBrowser} from '@angular/platform-browser';
import {AppModuleNgFactory} from './app.ngfactory';
platformBrowser().bootstrapModuleFactory(AppModuleNgFactory, {ngZone: 'noop'});
const helloWorldEl = document.querySelector('hello-world-el');
const input = document.querySelector('input[type=text]');
if(input){
input.addEventListener('input', e => {
const newText = (e.target as any).value;
helloWorldEl.setAttribute('name', newText);
});
}

View File

@ -0,0 +1,20 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Slot Test</title>
<base href="/">
</head>
<body>
<test-card>
<span slot="card-header">TestCardTitle</span>
<p>TestCardContent</p>
<span slot="card-footer">TestCardFooter</span>
</test-card>
<script src="dist/bundle.js"></script>
</body>
</html>

View File

@ -0,0 +1,30 @@
{
"angularCompilerOptions": {
"annotationsAs": "static fields",
"annotateForClosureCompiler": true,
"alwaysCompileGeneratedCode": true
},
"compilerOptions": {
"module": "es2015",
"moduleResolution": "node",
// TODO(i): strictNullChecks should turned on but are temporarily disabled due to #15432
"strictNullChecks": false,
"target": "es6",
"noImplicitAny": false,
"sourceMap": false,
"experimentalDecorators": true,
"outDir": "built",
"rootDir": ".",
"declaration": true,
"types": []
},
"exclude": [
"vendor",
"node_modules",
"built",
"dist",
"e2e"
]
}

File diff suppressed because it is too large Load Diff

View File

@ -49,7 +49,7 @@ if (browserDetection.supportsCustomElements && browserDetection.supportsShadowDo
});
it('should use slots to project content', () => {
const tpl = `<default-slot-el><span class="projected"></span></default-slot-el>`
const tpl = `<default-slot-el><span class="projected"></span></default-slot-el>`;
testContainer.innerHTML = tpl;
const testEl = testContainer.querySelector('default-slot-el') !;
const content = testContainer.querySelector('span.projected') !;
@ -59,7 +59,7 @@ if (browserDetection.supportsCustomElements && browserDetection.supportsShadowDo
});
it('should use a named slot to project content', () => {
const tpl = `<named-slot-el><span class="projected" slot="header"></span></named-slot-el>`
const tpl = `<named-slot-el><span class="projected" slot="header"></span></named-slot-el>`;
testContainer.innerHTML = tpl;
const testEl = testContainer.querySelector('named-slot-el') !;
const content = testContainer.querySelector('span.projected') !;
@ -73,7 +73,7 @@ if (browserDetection.supportsCustomElements && browserDetection.supportsShadowDo
<named-slots-el>
<span class="projected-header" slot="header"></span>
<span class="projected-body" slot="body"></span>
</named-slots-el>`
</named-slots-el>`;
testContainer.innerHTML = tpl;
const testEl = testContainer.querySelector('named-slots-el') !;
const headerContent = testContainer.querySelector('span.projected-header') !;
@ -90,7 +90,7 @@ if (browserDetection.supportsCustomElements && browserDetection.supportsShadowDo
const tpl = `
<slot-events-el>
<span class="projected">Content</span>
</slot-events-el>`
</slot-events-el>`;
templateEl.innerHTML = tpl;
const template = templateEl.content.cloneNode(true) as DocumentFragment;
const testEl = template.querySelector('slot-events-el') !as NgElement & SlotEventsComponent;
@ -157,13 +157,12 @@ class SlotEventsComponent {
}
}
const testElements =
[
DefaultSlotComponent, NamedSlotComponent, NamedSlotsComponent, DefaultSlotsComponent,
SlotEventsComponent
]
const testElements = [
DefaultSlotComponent, NamedSlotComponent, NamedSlotsComponent, DefaultSlotsComponent,
SlotEventsComponent
];
@NgModule({imports: [BrowserModule], declarations: testElements, entryComponents: testElements})
class TestModule {
@NgModule({imports: [BrowserModule], declarations: testElements, entryComponents: testElements})
class TestModule {
ngDoBootstrap() {}
}