build: switch example e2e tests to bazel (#28402)
* No longer builds the example e2e tests using "tsc". The examples are now built with Bazel and can therefore be built with Ivy by using the `--define=compile=aot` switch. * No longer runs the example e2e tests using the protractor CLI. example e2e tests are executed with the Bazel protractor rule and can therefore run incrementally. NOTE: Unit tests found within the examples are still running within the legacy jobs. PR Close #28402
This commit is contained in:
parent
66335c36e6
commit
98e5af1480
|
@ -410,7 +410,6 @@ jobs:
|
|||
- *define_env_vars
|
||||
- *yarn_install
|
||||
- run: yarn tsc -p packages
|
||||
- run: yarn tsc -p packages/examples
|
||||
- run: yarn tsc -p modules
|
||||
- run: yarn karma start ./karma-js.conf.js --single-run --browsers=ChromeNoSandbox
|
||||
|
||||
|
@ -437,7 +436,6 @@ jobs:
|
|||
command: ./scripts/saucelabs/start-tunnel.sh
|
||||
background: true
|
||||
- run: yarn tsc -p packages
|
||||
- run: yarn tsc -p packages/examples
|
||||
- run: yarn tsc -p modules
|
||||
# Waits for the Saucelabs tunnel to be ready. This ensures that we don't run tests
|
||||
# too early without Saucelabs not being ready.
|
||||
|
@ -465,10 +463,9 @@ jobs:
|
|||
- run: ./scripts/build-e2e-tests.sh --use-existing-packages-dist
|
||||
- run:
|
||||
name: Starting servers for e2e tests
|
||||
command: yarn gulp serve serve-examples
|
||||
command: yarn gulp serve
|
||||
background: true
|
||||
- run: NODE_PATH=$NODE_PATH:./dist/all yarn protractor ./protractor-e2e.conf.js --bundles=true
|
||||
- run: NODE_PATH=$NODE_PATH:./dist/all yarn protractor ./protractor-examples-e2e.conf.js --bundles=true
|
||||
- run: NODE_PATH=$NODE_PATH:./dist/all yarn protractor ./protractor-perf.conf.js --bundles=true --dryrun
|
||||
|
||||
legacy-misc-tests:
|
||||
|
|
|
@ -39,7 +39,6 @@ gulp.task('source-map-test', loadTask('source-map-test'));
|
|||
gulp.task('tools:build', loadTask('tools-build'));
|
||||
gulp.task('check-cycle', loadTask('check-cycle'));
|
||||
gulp.task('serve', loadTask('serve', 'default'));
|
||||
gulp.task('serve-examples', loadTask('serve', 'examples'));
|
||||
gulp.task('changelog', loadTask('changelog'));
|
||||
gulp.task('check-env', () => {/* this is a noop because the env test ran already above */});
|
||||
gulp.task('cldr:extract', loadTask('cldr', 'extract'));
|
||||
|
|
|
@ -38,12 +38,14 @@
|
|||
"@bazel/karma": "~0.22.1",
|
||||
"@bazel/typescript": "~0.22.1",
|
||||
"@schematics/angular": "^7.0.4",
|
||||
"@types/angular": "^1.6.47",
|
||||
"@types/chokidar": "1.7.3",
|
||||
"@types/convert-source-map": "^1.5.1",
|
||||
"@types/diff": "^3.2.2",
|
||||
"@types/fs-extra": "4.0.2",
|
||||
"@types/hammerjs": "2.0.35",
|
||||
"@types/jasmine": "^2.8.8",
|
||||
"@types/jasminewd2": "^2.0.6",
|
||||
"@types/mock-fs": "^3.6.30",
|
||||
"@types/node": "^10.9.4",
|
||||
"@types/selenium-webdriver": "3.0.7",
|
||||
|
@ -98,9 +100,7 @@
|
|||
"@bazel/bazel": "~0.22.0",
|
||||
"@bazel/buildifier": "^0.19.2",
|
||||
"@bazel/ibazel": "~0.9.0",
|
||||
"@types/angular": "^1.6.47",
|
||||
"@types/base64-js": "1.2.5",
|
||||
"@types/jasminewd2": "^2.0.4",
|
||||
"@types/minimist": "^1.2.0",
|
||||
"@types/systemjs": "0.19.32",
|
||||
"browserstacktunnel-wrapper": "2.0.1",
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
exports_files([
|
||||
"index.html",
|
||||
"tsconfig-e2e.json",
|
||||
])
|
|
@ -7,28 +7,15 @@ behavior) just like an Angular application developer would write.
|
|||
# Running the examples
|
||||
|
||||
```
|
||||
# # execute the following command only when framework code changes
|
||||
./build.sh
|
||||
# Serving individual examples (e.g. common)
|
||||
yarn bazel run //packages/examples/common:devserver
|
||||
|
||||
# run when test change
|
||||
./packages/examples/build.sh
|
||||
|
||||
# start server
|
||||
$(npm bin)/gulp serve-examples
|
||||
# "core" examples
|
||||
yarn bazel run //packages/examples/core:devserver
|
||||
```
|
||||
|
||||
navigate to [http://localhost:8001](http://localhost:8001)
|
||||
|
||||
# Running the tests
|
||||
|
||||
```
|
||||
# run only when framework code changes
|
||||
./build.sh
|
||||
|
||||
# run to compile tests and run them
|
||||
./packages/examples/test.sh
|
||||
yarn bazel test //packages/examples/...
|
||||
```
|
||||
|
||||
NOTE: sometimes the http server does not exit properly and it retains the `8001` port.
|
||||
in such a case you can use `lsof -i:8001` to see which process it is and then use `kill`
|
||||
to remove it. (Or in single command: `lsof -i:8001 -t | xargs kill`)
|
|
@ -1,21 +0,0 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
(function(global: any) {
|
||||
writeScriptTag('/vendor/zone.js');
|
||||
writeScriptTag('/vendor/task-tracking.js');
|
||||
writeScriptTag('/vendor/system.js');
|
||||
writeScriptTag('/vendor/Reflect.js');
|
||||
writeScriptTag('/_common/system-config.js');
|
||||
if (location.pathname.indexOf('/upgrade/') != -1) {
|
||||
writeScriptTag('/vendor/angular.js');
|
||||
}
|
||||
|
||||
function writeScriptTag(scriptUrl: string, onload: string = '') {
|
||||
document.write('<script src="' + scriptUrl + '" onload="' + onload + '"></script>');
|
||||
}
|
||||
}(window));
|
|
@ -1,26 +0,0 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
/* tslint:disable:no-console */
|
||||
import * as webdriver from 'selenium-webdriver';
|
||||
declare var browser: any;
|
||||
declare var expect: any;
|
||||
|
||||
// TODO (juliemr): remove this method once this becomes a protractor plugin
|
||||
export function verifyNoBrowserErrors() {
|
||||
browser.manage().logs().get('browser').then(function(browserLog: any[]) {
|
||||
const errors: any[] = [];
|
||||
browserLog.filter(logEntry => {
|
||||
const msg = logEntry.message;
|
||||
console.log('>> ' + msg);
|
||||
if (logEntry.level.value >= webdriver.logging.Level.INFO.value) {
|
||||
errors.push(msg);
|
||||
}
|
||||
});
|
||||
expect(errors).toEqual([]);
|
||||
});
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="shortcut icon" href="data:image/x-icon;," type="image/x-icon" />
|
||||
<script type="text/javascript" src="bootstrap.js"></script>
|
||||
<script type="text/javascript">
|
||||
System.import('main-dynamic').catch(console.error.bind(console));
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<example-app>
|
||||
loading...
|
||||
</example-app>
|
||||
</body>
|
||||
</html>
|
|
@ -1,19 +0,0 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
DO NOT DELETE THIS FILE
|
||||
=======================
|
||||
|
||||
The purpose of this file is to allow `main-dynamic.ts` to be tsc-compiled
|
||||
BEFORE it is copied over to each of the associated example directories
|
||||
within `dist/examples`.
|
||||
|
||||
*/
|
||||
export class AppModule {};
|
|
@ -1,36 +0,0 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
System.config({
|
||||
defaultJSExtensions: true,
|
||||
map: {
|
||||
'@angular/common': '/vendor/@angular/common/bundles/common.umd.js',
|
||||
'@angular/compiler': '/vendor/@angular/compiler/bundles/compiler.umd.js',
|
||||
'@angular/animations': '/vendor/@angular/animations/bundles/animations.umd.js',
|
||||
'@angular/animations/browser': '/vendor/@angular/animations/bundles/animations-browser.umd.js',
|
||||
'@angular/platform-browser/animations':
|
||||
'/vendor/@angular/platform-browser/bundles/platform-browser-animations.umd.js',
|
||||
'@angular/core': '/vendor/@angular/core/bundles/core.umd.js',
|
||||
'@angular/forms': '/vendor/@angular/forms/bundles/forms.umd.js',
|
||||
'@angular/http': '/vendor/@angular/forms/bundles/http.umd.js',
|
||||
'@angular/platform-browser':
|
||||
'/vendor/@angular/platform-browser/bundles/platform-browser.umd.js',
|
||||
'@angular/platform-browser-dynamic':
|
||||
'/vendor/@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
|
||||
'@angular/router': '/vendor/@angular/router/bundles/router.umd.js',
|
||||
'@angular/upgrade': '/vendor/@angular/upgrade/bundles/upgrade.umd.js',
|
||||
'@angular/upgrade/static': '/vendor/@angular/upgrade/bundles/upgrade-static.umd.js',
|
||||
'rxjs': '/vendor/rxjs'
|
||||
},
|
||||
packages: {
|
||||
'rxjs/ajax': {main: 'index.js', defaultExtension: 'js'},
|
||||
'rxjs/operators': {main: 'index.js', defaultExtension: 'js'},
|
||||
'rxjs/testing': {main: 'index.js', defaultExtension: 'js'},
|
||||
'rxjs/websocket': {main: 'index.js', defaultExtension: 'js'},
|
||||
'rxjs': {main: 'index.js', defaultExtension: 'js'},
|
||||
},
|
||||
});
|
|
@ -1,44 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -u -e -o pipefail
|
||||
|
||||
#
|
||||
# This script is used to compile and copy the contents for each of
|
||||
# example directories over to the dist/examples directory so that they
|
||||
# can be tested with karma and protractor. The `gulp serve-examples` command
|
||||
# can be used to run each of the examples in isolation via http as well.
|
||||
#
|
||||
|
||||
(
|
||||
cd `dirname $0`
|
||||
|
||||
DIST="../../dist/examples";
|
||||
rm -rf -- $DIST
|
||||
$(npm bin)/tsc -p ./tsconfig-build.json --importHelpers false
|
||||
|
||||
mkdir $DIST/vendor/
|
||||
|
||||
ln -s ../../../dist/packages-dist/ $DIST/vendor/@angular
|
||||
|
||||
for FILE in \
|
||||
../../../node_modules/angular/angular.js \
|
||||
../../../node_modules/zone.js/dist/zone.js \
|
||||
../../../node_modules/zone.js/dist/task-tracking.js \
|
||||
../../../node_modules/systemjs/dist/system.js \
|
||||
../../../node_modules/reflect-metadata/Reflect.js \
|
||||
../../../node_modules/rxjs
|
||||
do
|
||||
ln -s $FILE $DIST/vendor/`basename $FILE`
|
||||
done
|
||||
|
||||
for MODULE in `find . -name module.ts`; do
|
||||
FINAL_DIR_PATH=$DIST/`dirname $MODULE`
|
||||
|
||||
echo "==== $MODULE"
|
||||
cp _common/*.html $FINAL_DIR_PATH
|
||||
cp $DIST/_common/*.js $FINAL_DIR_PATH
|
||||
cp $DIST/_common/*.js.map $FINAL_DIR_PATH
|
||||
|
||||
find `dirname $MODULE` -name \*.css -exec cp {} $FINAL_DIR_PATH \;
|
||||
done
|
||||
)
|
|
@ -0,0 +1,63 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load("//packages/bazel:index.bzl", "protractor_web_test_suite")
|
||||
load("//tools:defaults.bzl", "ng_module", "ts_library")
|
||||
load("@build_bazel_rules_typescript//:defs.bzl", "ts_devserver")
|
||||
|
||||
ng_module(
|
||||
name = "common_examples",
|
||||
srcs = glob(
|
||||
["**/*.ts"],
|
||||
exclude = ["**/*_spec.ts"],
|
||||
),
|
||||
# TODO: FW-1004 Type checking is currently not complete.
|
||||
type_check = False,
|
||||
deps = [
|
||||
"//packages/common",
|
||||
"//packages/core",
|
||||
"//packages/platform-browser",
|
||||
"//packages/platform-browser-dynamic",
|
||||
"//packages/router",
|
||||
"@rxjs",
|
||||
],
|
||||
)
|
||||
|
||||
ts_library(
|
||||
name = "common_tests_lib",
|
||||
testonly = True,
|
||||
srcs = glob(["**/*_spec.ts"]),
|
||||
tsconfig = "//packages/examples:tsconfig-e2e.json",
|
||||
deps = [
|
||||
"//packages/examples/test-utils",
|
||||
"//packages/private/testing",
|
||||
"@ngdeps//@types/jasminewd2",
|
||||
"@ngdeps//protractor",
|
||||
],
|
||||
)
|
||||
|
||||
ts_devserver(
|
||||
name = "devserver",
|
||||
entry_module = "@angular/examples/common/main",
|
||||
index_html = "//packages/examples:index.html",
|
||||
port = 4200,
|
||||
scripts = ["@ngdeps//node_modules/tslib:tslib.js"],
|
||||
static_files = [
|
||||
"@ngdeps//node_modules/zone.js:dist/zone.js",
|
||||
# This is needed because the "ngComponentOutlet" test uses the JIT compiler
|
||||
# and needs to be able to read metadata at runtime.
|
||||
"@ngdeps//node_modules/reflect-metadata:Reflect.js",
|
||||
],
|
||||
deps = [":common_examples"],
|
||||
)
|
||||
|
||||
protractor_web_test_suite(
|
||||
name = "protractor_tests",
|
||||
data = ["//packages/bazel/src/protractor/utils"],
|
||||
on_prepare = ":start-server.js",
|
||||
server = ":devserver",
|
||||
deps = [
|
||||
":common_tests_lib",
|
||||
"@ngdeps//protractor",
|
||||
"@ngdeps//selenium-webdriver",
|
||||
],
|
||||
)
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
import {$, browser, by, element, protractor} from 'protractor';
|
||||
|
||||
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
|
||||
import {verifyNoBrowserErrors} from '../../../../test-utils';
|
||||
|
||||
|
||||
function waitForElement(selector: string) {
|
||||
|
@ -21,10 +21,9 @@ describe('Location', () => {
|
|||
afterEach(verifyNoBrowserErrors);
|
||||
|
||||
it('should verify paths', () => {
|
||||
browser.get('/common/location/ts/#/bar/baz');
|
||||
browser.get('/location/#/bar/baz');
|
||||
waitForElement('hash-location');
|
||||
expect(element.all(by.css('path-location code')).get(0).getText())
|
||||
.toEqual('/common/location/ts');
|
||||
expect(element.all(by.css('path-location code')).get(0).getText()).toEqual('/location');
|
||||
expect(element.all(by.css('hash-location code')).get(0).getText()).toEqual('/bar/baz');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -17,14 +17,13 @@ import {PathLocationComponent} from './path_location_component';
|
|||
selector: 'example-app',
|
||||
template: `<hash-location></hash-location><path-location></path-location>`
|
||||
})
|
||||
export class ExampleAppComponent {
|
||||
export class AppComponent {
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
declarations: [ExampleAppComponent, PathLocationComponent, HashLocationComponent],
|
||||
declarations: [AppComponent, PathLocationComponent, HashLocationComponent],
|
||||
providers: [{provide: APP_BASE_HREF, useValue: '/'}],
|
||||
imports: [BrowserModule],
|
||||
bootstrap: [ExampleAppComponent]
|
||||
})
|
||||
export class AppModule {
|
||||
}
|
||||
|
|
|
@ -5,9 +5,8 @@
|
|||
* 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
|
||||
*/
|
||||
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
|
||||
import * as mod from './module';
|
||||
|
||||
if (mod.AppModule) {
|
||||
platformBrowserDynamic().bootstrapModule(mod.AppModule);
|
||||
}
|
||||
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
|
||||
import {TestsAppModuleNgFactory} from './test_module.ngfactory';
|
||||
|
||||
platformBrowserDynamic().bootstrapModuleFactory(TestsAppModuleNgFactory);
|
|
@ -7,7 +7,8 @@
|
|||
*/
|
||||
|
||||
import {$, ExpectedConditions, browser, by, element} from 'protractor';
|
||||
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
|
||||
|
||||
import {verifyNoBrowserErrors} from '../../../../test-utils';
|
||||
|
||||
function waitForElement(selector: string) {
|
||||
const EC = ExpectedConditions;
|
||||
|
|
|
@ -7,21 +7,22 @@
|
|||
*/
|
||||
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {Compiler, Component, Injectable, Injector, NgModule, NgModuleFactory} from '@angular/core';
|
||||
import {COMPILER_OPTIONS, Compiler, CompilerFactory, Component, Injectable, Injector, NgModule, NgModuleFactory} from '@angular/core';
|
||||
import {BrowserModule} from '@angular/platform-browser';
|
||||
import {JitCompilerFactory} from '@angular/platform-browser-dynamic';
|
||||
|
||||
|
||||
|
||||
// #docregion SimpleExample
|
||||
@Component({selector: 'hello-world', template: 'Hello World!'})
|
||||
class HelloWorld {
|
||||
export class HelloWorld {
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'ng-component-outlet-simple-example',
|
||||
template: `<ng-container *ngComponentOutlet="HelloWorld"></ng-container>`
|
||||
})
|
||||
class NgTemplateOutletSimpleExample {
|
||||
export class NgTemplateOutletSimpleExample {
|
||||
// This field is necessary to expose HelloWorld to the template.
|
||||
HelloWorld = HelloWorld;
|
||||
}
|
||||
|
@ -29,7 +30,7 @@ class NgTemplateOutletSimpleExample {
|
|||
|
||||
// #docregion CompleteExample
|
||||
@Injectable()
|
||||
class Greeter {
|
||||
export class Greeter {
|
||||
suffix = '!';
|
||||
}
|
||||
|
||||
|
@ -37,7 +38,7 @@ class Greeter {
|
|||
selector: 'complete-component',
|
||||
template: `Complete: <ng-content></ng-content> <ng-content></ng-content>{{ greeter.suffix }}`
|
||||
})
|
||||
class CompleteComponent {
|
||||
export class CompleteComponent {
|
||||
constructor(public greeter: Greeter) {}
|
||||
}
|
||||
|
||||
|
@ -48,7 +49,7 @@ class CompleteComponent {
|
|||
injector: myInjector;
|
||||
content: myContent"></ng-container>`
|
||||
})
|
||||
class NgTemplateOutletCompleteExample {
|
||||
export class NgTemplateOutletCompleteExample {
|
||||
// This field is necessary to expose CompleteComponent to the template.
|
||||
CompleteComponent = CompleteComponent;
|
||||
myInjector: Injector;
|
||||
|
@ -64,7 +65,7 @@ class NgTemplateOutletCompleteExample {
|
|||
|
||||
// #docregion NgModuleFactoryExample
|
||||
@Component({selector: 'other-module-component', template: `Other Module Component!`})
|
||||
class OtherModuleComponent {
|
||||
export class OtherModuleComponent {
|
||||
}
|
||||
|
||||
@Component({
|
||||
|
@ -73,7 +74,7 @@ class OtherModuleComponent {
|
|||
<ng-container *ngComponentOutlet="OtherModuleComponent;
|
||||
ngModuleFactory: myModule;"></ng-container>`
|
||||
})
|
||||
class NgTemplateOutletOtherModuleExample {
|
||||
export class NgTemplateOutletOtherModuleExample {
|
||||
// This field is necessary to expose OtherModuleComponent to the template.
|
||||
OtherModuleComponent = OtherModuleComponent;
|
||||
myModule: NgModuleFactory<any>;
|
||||
|
@ -91,19 +92,7 @@ class NgTemplateOutletOtherModuleExample {
|
|||
<hr/>
|
||||
<ng-component-outlet-other-module-example></ng-component-outlet-other-module-example>`
|
||||
})
|
||||
class ExampleApp {
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
imports: [BrowserModule],
|
||||
declarations: [
|
||||
ExampleApp, NgTemplateOutletSimpleExample, NgTemplateOutletCompleteExample,
|
||||
NgTemplateOutletOtherModuleExample, HelloWorld, CompleteComponent
|
||||
],
|
||||
entryComponents: [HelloWorld, CompleteComponent],
|
||||
bootstrap: [ExampleApp]
|
||||
})
|
||||
export class AppModule {
|
||||
export class AppComponent {
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
|
@ -113,3 +102,26 @@ export class AppModule {
|
|||
})
|
||||
export class OtherModule {
|
||||
}
|
||||
|
||||
export function createCompiler(compilerFactory: CompilerFactory) {
|
||||
return compilerFactory.createCompiler();
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
imports: [BrowserModule],
|
||||
declarations: [
|
||||
AppComponent, NgTemplateOutletSimpleExample, NgTemplateOutletCompleteExample,
|
||||
NgTemplateOutletOtherModuleExample, HelloWorld, CompleteComponent
|
||||
],
|
||||
entryComponents: [HelloWorld, CompleteComponent],
|
||||
providers: [
|
||||
// Setup the JIT compiler that is not set up by default because the examples
|
||||
// are bootstrapped using their NgModule factory. Since this example uses the
|
||||
// JIT compiler, we manually set it up for this module.
|
||||
{provide: COMPILER_OPTIONS, useValue: {}, multi: true},
|
||||
{provide: CompilerFactory, useClass: JitCompilerFactory, deps: [COMPILER_OPTIONS]},
|
||||
{provide: Compiler, useFactory: createCompiler, deps: [CompilerFactory]}
|
||||
]
|
||||
})
|
||||
export class AppModule {
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import {$, ExpectedConditions, browser, by, element} from 'protractor';
|
||||
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
|
||||
import {verifyNoBrowserErrors} from '../../../../test-utils';
|
||||
|
||||
function waitForElement(selector: string) {
|
||||
const EC = ExpectedConditions;
|
||||
|
@ -16,7 +16,7 @@ function waitForElement(selector: string) {
|
|||
}
|
||||
|
||||
describe('ngIf', () => {
|
||||
const URL = 'common/ngIf/ts/';
|
||||
const URL = '/ngIf';
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
|
||||
describe('ng-if-simple', () => {
|
||||
|
|
|
@ -21,7 +21,7 @@ import {Subject} from 'rxjs';
|
|||
<div *ngIf="show">Text to show</div>
|
||||
`
|
||||
})
|
||||
class NgIfSimple {
|
||||
export class NgIfSimple {
|
||||
show: boolean = true;
|
||||
}
|
||||
// #enddocregion
|
||||
|
@ -37,7 +37,7 @@ class NgIfSimple {
|
|||
<ng-template #elseBlock>Alternate text while primary text is hidden</ng-template>
|
||||
`
|
||||
})
|
||||
class NgIfElse {
|
||||
export class NgIfElse {
|
||||
show: boolean = true;
|
||||
}
|
||||
// #enddocregion
|
||||
|
@ -56,7 +56,7 @@ class NgIfElse {
|
|||
<ng-template #elseBlock>Alternate text while primary text is hidden</ng-template>
|
||||
`
|
||||
})
|
||||
class NgIfThenElse implements OnInit {
|
||||
export class NgIfThenElse implements OnInit {
|
||||
thenBlock: TemplateRef<any>|null = null;
|
||||
show: boolean = true;
|
||||
|
||||
|
@ -85,7 +85,7 @@ class NgIfThenElse implements OnInit {
|
|||
<ng-template #loading let-user>Waiting... (user is {{user|json}})</ng-template>
|
||||
`
|
||||
})
|
||||
class NgIfAs {
|
||||
export class NgIfAs {
|
||||
userObservable = new Subject<{first: string, last: string}>();
|
||||
first = ['John', 'Mike', 'Mary', 'Bob'];
|
||||
firstIndex = 0;
|
||||
|
@ -116,13 +116,12 @@ class NgIfAs {
|
|||
<hr>
|
||||
`
|
||||
})
|
||||
class ExampleApp {
|
||||
export class AppComponent {
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
imports: [BrowserModule],
|
||||
declarations: [ExampleApp, NgIfSimple, NgIfElse, NgIfThenElse, NgIfAs],
|
||||
bootstrap: [ExampleApp]
|
||||
declarations: [AppComponent, NgIfSimple, NgIfElse, NgIfThenElse, NgIfAs],
|
||||
})
|
||||
export class AppModule {
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import {$, ExpectedConditions, browser, by, element} from 'protractor';
|
||||
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
|
||||
import {verifyNoBrowserErrors} from '../../../../test-utils';
|
||||
|
||||
function waitForElement(selector: string) {
|
||||
const EC = ExpectedConditions;
|
||||
|
@ -16,7 +16,7 @@ function waitForElement(selector: string) {
|
|||
}
|
||||
|
||||
describe('ngTemplateOutlet', () => {
|
||||
const URL = 'common/ngTemplateOutlet/ts/';
|
||||
const URL = '/ngTemplateOutlet';
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
|
||||
describe('ng-template-outlet-example', () => {
|
||||
|
|
|
@ -26,7 +26,7 @@ import {BrowserModule} from '@angular/platform-browser';
|
|||
<ng-template #svk let-person="localSk"><span>Ahoj {{person}}!</span></ng-template>
|
||||
`
|
||||
})
|
||||
class NgTemplateOutletExample {
|
||||
export class NgTemplateOutletExample {
|
||||
myContext = {$implicit: 'World', localSk: 'Svet'};
|
||||
}
|
||||
// #enddocregion
|
||||
|
@ -36,13 +36,12 @@ class NgTemplateOutletExample {
|
|||
selector: 'example-app',
|
||||
template: `<ng-template-outlet-example></ng-template-outlet-example>`
|
||||
})
|
||||
class ExampleApp {
|
||||
export class AppComponent {
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
imports: [BrowserModule],
|
||||
declarations: [ExampleApp, NgTemplateOutletExample],
|
||||
bootstrap: [ExampleApp]
|
||||
declarations: [AppComponent, NgTemplateOutletExample],
|
||||
})
|
||||
export class AppModule {
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ export class AsyncObservablePipeComponent {
|
|||
// protractor will not see us. Also we want to have this outside the docregion so as not to confuse
|
||||
// the reader.
|
||||
function setInterval(fn: Function, delay: number) {
|
||||
const zone = Zone.current;
|
||||
const zone = (window as any)['Zone'].current;
|
||||
let rootZone = zone;
|
||||
while (rootZone.parent) {
|
||||
rootZone = rootZone.parent;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import {$, ExpectedConditions, browser, by, element} from 'protractor';
|
||||
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
|
||||
import {verifyNoBrowserErrors} from '../../../../test-utils';
|
||||
|
||||
function waitForElement(selector: string) {
|
||||
const EC = ExpectedConditions;
|
||||
|
@ -17,7 +17,7 @@ function waitForElement(selector: string) {
|
|||
|
||||
describe('pipe', () => {
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
const URL = '/common/pipes/ts/';
|
||||
const URL = '/pipes';
|
||||
|
||||
describe('async', () => {
|
||||
it('should resolve and display promise', () => {
|
||||
|
|
|
@ -59,19 +59,19 @@ import {TitleCasePipeComponent} from './titlecase_pipe';
|
|||
<keyvalue-pipe></keyvalue-pipe>
|
||||
`
|
||||
})
|
||||
export class ExampleAppComponent {
|
||||
export class AppComponent {
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AsyncPromisePipeComponent, AsyncObservablePipeComponent, ExampleAppComponent, JsonPipeComponent,
|
||||
AsyncPromisePipeComponent, AsyncObservablePipeComponent, AppComponent, JsonPipeComponent,
|
||||
DatePipeComponent, DeprecatedDatePipeComponent, LowerUpperPipeComponent, TitleCasePipeComponent,
|
||||
NumberPipeComponent, PercentPipeComponent, DeprecatedPercentPipeComponent,
|
||||
CurrencyPipeComponent, DeprecatedCurrencyPipeComponent, SlicePipeStringComponent,
|
||||
SlicePipeListComponent, I18nPluralPipeComponent, I18nSelectPipeComponent, KeyValuePipeComponent
|
||||
NumberPipeComponent, DeprecatedNumberPipeComponent, PercentPipeComponent,
|
||||
DeprecatedPercentPipeComponent, CurrencyPipeComponent, DeprecatedCurrencyPipeComponent,
|
||||
SlicePipeStringComponent, SlicePipeListComponent, I18nPluralPipeComponent,
|
||||
I18nSelectPipeComponent, KeyValuePipeComponent
|
||||
],
|
||||
imports: [BrowserModule],
|
||||
bootstrap: [ExampleAppComponent]
|
||||
})
|
||||
export class AppModule {
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
const protractorUtils = require('@angular/bazel/protractor-utils');
|
||||
const protractor = require('protractor');
|
||||
|
||||
module.exports = async function(config) {
|
||||
const {port} = await protractorUtils.runServer(config.workspace, config.server, '-port', []);
|
||||
const serverUrl = `http://localhost:${port}`;
|
||||
|
||||
protractor.browser.baseUrl = serverUrl;
|
||||
};
|
|
@ -0,0 +1,41 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
import {Component, NgModule} from '@angular/core';
|
||||
import {RouterModule} from '@angular/router';
|
||||
|
||||
import * as locationExample from './location/ts/module';
|
||||
import * as ngComponentOutletExample from './ngComponentOutlet/ts/module';
|
||||
import * as ngIfExample from './ngIf/ts/module';
|
||||
import * as ngTemplateOutletExample from './ngTemplateOutlet/ts/module';
|
||||
import * as pipesExample from './pipes/ts/module';
|
||||
|
||||
@Component({selector: 'example-app', template: '<router-outlet></router-outlet>'})
|
||||
export class TestsAppComponent {
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
locationExample.AppModule, ngComponentOutletExample.AppModule, ngIfExample.AppModule,
|
||||
ngTemplateOutletExample.AppModule, pipesExample.AppModule,
|
||||
|
||||
// Router configuration so that the individual e2e tests can load their
|
||||
// app components.
|
||||
RouterModule.forRoot([
|
||||
{path: 'location', component: locationExample.AppComponent},
|
||||
{path: 'ngComponentOutlet', component: ngComponentOutletExample.AppComponent},
|
||||
{path: 'ngIf', component: ngIfExample.AppComponent},
|
||||
{path: 'ngTemplateOutlet', component: ngTemplateOutletExample.AppComponent},
|
||||
{path: 'pipes', component: pipesExample.AppComponent},
|
||||
])
|
||||
],
|
||||
declarations: [TestsAppComponent],
|
||||
bootstrap: [TestsAppComponent]
|
||||
})
|
||||
export class TestsAppModule {
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load("//tools:defaults.bzl", "ng_module")
|
||||
|
||||
ng_module(
|
||||
name = "compiler_examples",
|
||||
srcs = glob(["**/*.ts"]),
|
||||
deps = [
|
||||
"//packages/core",
|
||||
"//packages/platform-browser",
|
||||
"//packages/platform-browser-dynamic",
|
||||
],
|
||||
)
|
|
@ -7,11 +7,13 @@
|
|||
*/
|
||||
|
||||
import {UrlResolver} from '@angular/compiler';
|
||||
import {NgModule} from '@angular/core';
|
||||
import {Component, NgModule} from '@angular/core';
|
||||
import {BrowserModule} from '@angular/platform-browser';
|
||||
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
|
||||
|
||||
let MyApp: any;
|
||||
@Component({selector: 'my-app', template: 'empty'})
|
||||
class MyApp {
|
||||
}
|
||||
|
||||
// #docregion url_resolver
|
||||
class MyUrlResolver extends UrlResolver {
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load("//packages/bazel:index.bzl", "protractor_web_test_suite")
|
||||
load("//tools:defaults.bzl", "ng_module", "ts_library")
|
||||
load("@build_bazel_rules_typescript//:defs.bzl", "ts_devserver")
|
||||
|
||||
ng_module(
|
||||
name = "core_examples",
|
||||
srcs = glob(
|
||||
["**/*.ts"],
|
||||
exclude = [
|
||||
"**/*_spec.ts",
|
||||
"**/*_howto.ts",
|
||||
],
|
||||
),
|
||||
# TODO: FW-1004 Type checking is currently not complete.
|
||||
type_check = False,
|
||||
deps = [
|
||||
"//packages/animations",
|
||||
"//packages/core",
|
||||
"//packages/platform-browser",
|
||||
"//packages/platform-browser-dynamic",
|
||||
"//packages/platform-browser/animations",
|
||||
"//packages/router",
|
||||
],
|
||||
)
|
||||
|
||||
ts_library(
|
||||
name = "core_e2e_tests_lib",
|
||||
testonly = True,
|
||||
srcs = glob(["**/e2e_test/*_spec.ts"]),
|
||||
tsconfig = "//packages/examples:tsconfig-e2e.json",
|
||||
deps = [
|
||||
"//packages/examples/test-utils",
|
||||
"@ngdeps//@types/jasminewd2",
|
||||
"@ngdeps//protractor",
|
||||
],
|
||||
)
|
||||
|
||||
ts_devserver(
|
||||
name = "devserver",
|
||||
entry_module = "@angular/examples/core/main",
|
||||
index_html = "//packages/examples:index.html",
|
||||
port = 4200,
|
||||
scripts = ["@ngdeps//node_modules/tslib:tslib.js"],
|
||||
static_files = [
|
||||
"@ngdeps//node_modules/zone.js:dist/zone.js",
|
||||
"@ngdeps//node_modules/zone.js:dist/task-tracking.js",
|
||||
],
|
||||
deps = [":core_examples"],
|
||||
)
|
||||
|
||||
protractor_web_test_suite(
|
||||
name = "protractor_tests",
|
||||
data = ["//packages/bazel/src/protractor/utils"],
|
||||
on_prepare = ":start-server.js",
|
||||
server = ":devserver",
|
||||
deps = [
|
||||
":core_e2e_tests_lib",
|
||||
"@ngdeps//protractor",
|
||||
"@ngdeps//selenium-webdriver",
|
||||
],
|
||||
)
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import {$, ExpectedConditions, browser, by, element} from 'protractor';
|
||||
import {verifyNoBrowserErrors} from '../../../../../_common/e2e_util';
|
||||
import {verifyNoBrowserErrors} from '../../../../../test-utils';
|
||||
|
||||
function waitForElement(selector: string) {
|
||||
const EC = ExpectedConditions;
|
||||
|
@ -19,7 +19,7 @@ describe('animation example', () => {
|
|||
afterEach(verifyNoBrowserErrors);
|
||||
|
||||
describe('index view', () => {
|
||||
const URL = '/core/animation/ts/dsl/';
|
||||
const URL = '/animation/dsl/';
|
||||
|
||||
it('should list out the current collection of items', () => {
|
||||
browser.get(URL);
|
||||
|
|
|
@ -5,4 +5,5 @@
|
|||
* 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
|
||||
*/
|
||||
export {AppModule} from './animation_example';
|
||||
|
||||
export {AppModule, MyExpandoCmp as AppComponent} from './animation_example';
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import {ElementFinder, browser, by, element} from 'protractor';
|
||||
import {verifyNoBrowserErrors} from '../../../../../_common/e2e_util';
|
||||
import {verifyNoBrowserErrors} from '../../../../../test-utils';
|
||||
|
||||
describe('contentChild example', () => {
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
|
@ -15,7 +15,7 @@ describe('contentChild example', () => {
|
|||
let result: ElementFinder;
|
||||
|
||||
beforeEach(() => {
|
||||
browser.get('/core/di/ts/contentChild/index.html');
|
||||
browser.get('/di/contentChild');
|
||||
button = element(by.css('button'));
|
||||
result = element(by.css('div'));
|
||||
});
|
||||
|
|
|
@ -17,3 +17,5 @@ import {ContentChildComp, Pane, Tab} from './content_child_example';
|
|||
})
|
||||
export class AppModule {
|
||||
}
|
||||
|
||||
export {ContentChildComp as AppComponent};
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import {ElementFinder, browser, by, element} from 'protractor';
|
||||
import {verifyNoBrowserErrors} from '../../../../../_common/e2e_util';
|
||||
import {verifyNoBrowserErrors} from '../../../../../test-utils';
|
||||
|
||||
describe('contentChildren example', () => {
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
|
@ -16,7 +16,7 @@ describe('contentChildren example', () => {
|
|||
let resultNested: ElementFinder;
|
||||
|
||||
beforeEach(() => {
|
||||
browser.get('/core/di/ts/contentChildren/index.html');
|
||||
browser.get('/di/contentChildren');
|
||||
button = element(by.css('button'));
|
||||
resultTopLevel = element(by.css('.top-level'));
|
||||
resultNested = element(by.css('.nested'));
|
||||
|
|
|
@ -17,3 +17,5 @@ import {ContentChildrenComp, Pane, Tab} from './content_children_example';
|
|||
})
|
||||
export class AppModule {
|
||||
}
|
||||
|
||||
export {ContentChildrenComp as AppComponent};
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import {ElementFinder, browser, by, element} from 'protractor';
|
||||
import {verifyNoBrowserErrors} from '../../../../../_common/e2e_util';
|
||||
import {verifyNoBrowserErrors} from '../../../../../test-utils';
|
||||
|
||||
describe('viewChild example', () => {
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
|
@ -15,7 +15,7 @@ describe('viewChild example', () => {
|
|||
let result: ElementFinder;
|
||||
|
||||
beforeEach(() => {
|
||||
browser.get('/core/di/ts/viewChild/index.html');
|
||||
browser.get('/di/viewChild');
|
||||
button = element(by.css('button'));
|
||||
result = element(by.css('div'));
|
||||
});
|
||||
|
|
|
@ -15,3 +15,5 @@ import {Pane, ViewChildComp} from './view_child_example';
|
|||
{imports: [BrowserModule], declarations: [ViewChildComp, Pane], bootstrap: [ViewChildComp]})
|
||||
export class AppModule {
|
||||
}
|
||||
|
||||
export {ViewChildComp as AppComponent};
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
|
||||
import {ElementFinder, browser, by, element} from 'protractor';
|
||||
import {verifyNoBrowserErrors} from '../../../../../_common/e2e_util';
|
||||
import {verifyNoBrowserErrors} from '../../../../../test-utils';
|
||||
|
||||
describe('viewChildren example', () => {
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
|
@ -16,7 +16,7 @@ describe('viewChildren example', () => {
|
|||
let result: ElementFinder;
|
||||
|
||||
beforeEach(() => {
|
||||
browser.get('/core/di/ts/viewChildren/index.html');
|
||||
browser.get('/di/viewChildren');
|
||||
button = element(by.css('button'));
|
||||
result = element(by.css('div'));
|
||||
});
|
||||
|
|
|
@ -18,3 +18,5 @@ import {Pane, ViewChildrenComp} from './view_children_example';
|
|||
})
|
||||
export class AppModule {
|
||||
}
|
||||
|
||||
export {ViewChildrenComp as AppComponent};
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
|
||||
import {TestsAppModuleNgFactory} from './test_module.ngfactory';
|
||||
|
||||
platformBrowserDynamic().bootstrapModuleFactory(TestsAppModuleNgFactory);
|
|
@ -0,0 +1,17 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
const protractorUtils = require('@angular/bazel/protractor-utils');
|
||||
const protractor = require('protractor');
|
||||
|
||||
module.exports = async function(config) {
|
||||
const {port} = await protractorUtils.runServer(config.workspace, config.server, '-port', []);
|
||||
const serverUrl = `http://localhost:${port}`;
|
||||
|
||||
protractor.browser.baseUrl = serverUrl;
|
||||
};
|
|
@ -0,0 +1,44 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
import {Component, NgModule} from '@angular/core';
|
||||
import {RouterModule} from '@angular/router';
|
||||
|
||||
import * as animationDslExample from './animation/ts/dsl/module';
|
||||
import * as diContentChildExample from './di/ts/contentChild/module';
|
||||
import * as diContentChildrenExample from './di/ts/contentChildren/module';
|
||||
import * as diViewChildExample from './di/ts/viewChild/module';
|
||||
import * as diViewChildrenExample from './di/ts/viewChildren/module';
|
||||
import * as testabilityWhenStableExample from './testability/ts/whenStable/module';
|
||||
|
||||
@Component({selector: 'example-app', template: '<router-outlet></router-outlet>'})
|
||||
export class TestsAppComponent {
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
animationDslExample.AppModule, diContentChildExample.AppModule,
|
||||
diContentChildrenExample.AppModule, diViewChildExample.AppModule,
|
||||
diViewChildrenExample.AppModule, testabilityWhenStableExample.AppModule,
|
||||
|
||||
// Router configuration so that the individual e2e tests can load their
|
||||
// app components.
|
||||
RouterModule.forRoot([
|
||||
{path: 'animation/dsl', component: animationDslExample.AppComponent},
|
||||
{path: 'di/contentChild', component: diContentChildExample.AppComponent},
|
||||
{path: 'di/contentChildren', component: diContentChildrenExample.AppComponent},
|
||||
{path: 'di/viewChild', component: diViewChildExample.AppComponent},
|
||||
{path: 'di/viewChildren', component: diViewChildrenExample.AppComponent},
|
||||
{path: 'testability/whenStable', component: testabilityWhenStableExample.AppComponent},
|
||||
])
|
||||
],
|
||||
declarations: [TestsAppComponent],
|
||||
bootstrap: [TestsAppComponent]
|
||||
})
|
||||
export class TestsAppModule {
|
||||
}
|
|
@ -7,13 +7,19 @@
|
|||
*/
|
||||
|
||||
import {browser, by, element} from 'protractor';
|
||||
import {verifyNoBrowserErrors} from '../../../../../_common/e2e_util';
|
||||
import {verifyNoBrowserErrors} from '../../../../../test-utils';
|
||||
|
||||
// Declare the global "window" and "document" constant since we don't want to add the "dom"
|
||||
// TypeScript lib for the e2e specs that execute code in the browser and reference such
|
||||
// global constants.
|
||||
declare const window: any;
|
||||
declare const document: any;
|
||||
|
||||
describe('testability example', () => {
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
|
||||
describe('using task tracking', () => {
|
||||
const URL = '/core/testability/ts/whenStable/';
|
||||
const URL = '/testability/whenStable/';
|
||||
|
||||
it('times out with a list of tasks', done => {
|
||||
browser.get(URL);
|
||||
|
@ -22,7 +28,7 @@ describe('testability example', () => {
|
|||
// Script that runs in the browser and calls whenStable with a timeout.
|
||||
let waitWithResultScript = function(done: any) {
|
||||
let rootEl = document.querySelector('example-app');
|
||||
let testability = (window as any).getAngularTestability(rootEl);
|
||||
let testability = window.getAngularTestability(rootEl);
|
||||
testability.whenStable((didWork: boolean, tasks: any) => { done(tasks); }, 1000);
|
||||
};
|
||||
|
||||
|
|
|
@ -5,4 +5,4 @@
|
|||
* 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
|
||||
*/
|
||||
export {AppModule} from './testability_example';
|
||||
export {AppModule, StableTestCmp as AppComponent} from './testability_example';
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
load("//tools:defaults.bzl", "jasmine_node_test", "ts_library")
|
||||
|
||||
ts_library(
|
||||
name = "fake_async_lib",
|
||||
srcs = [
|
||||
"example_spec.ts",
|
||||
"fake_async.ts",
|
||||
],
|
||||
deps = [
|
||||
"//packages/core/testing",
|
||||
"@ngdeps//@types/jasmine",
|
||||
"@ngdeps//@types/node",
|
||||
],
|
||||
)
|
||||
|
||||
jasmine_node_test(
|
||||
name = "test",
|
||||
bootstrap = ["angular/tools/testing/init_node_spec.js"],
|
||||
deps = [
|
||||
":fake_async_lib",
|
||||
"//tools/testing:node",
|
||||
],
|
||||
)
|
|
@ -0,0 +1,12 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
// Import the "fake_async" example that registers tests which are shown as examples. These need
|
||||
// to be valid tests, so we run them here. Note that we need to add this layer of abstraction here
|
||||
// because the "jasmine_node_test" rule only picks up test files with the "_spec.ts" file suffix.
|
||||
import './fake_async';
|
|
@ -6,7 +6,7 @@
|
|||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
/* tslint:disable:no-console */
|
||||
import {Component, Directive, EventEmitter} from '@angular/core';
|
||||
import {Component, Directive, EventEmitter, NgModule} from '@angular/core';
|
||||
|
||||
// #docregion component-input
|
||||
@Component({
|
||||
|
@ -64,3 +64,9 @@ export class MyOutputComponent {
|
|||
onEveryFiveSeconds() { console.log('five seconds'); }
|
||||
}
|
||||
// #enddocregion component-output-interval
|
||||
|
||||
@NgModule({
|
||||
declarations: [BankAccountComponent, MyInputComponent, IntervalDirComponent, MyOutputComponent]
|
||||
})
|
||||
export class AppModule {
|
||||
}
|
||||
|
|
|
@ -13,8 +13,10 @@ import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
|
|||
import {MyComponent} from './my_component';
|
||||
|
||||
enableProdMode();
|
||||
@NgModule({imports: [BrowserModule], bootstrap: [MyComponent]})
|
||||
class AppModule {
|
||||
|
||||
@NgModule({imports: [BrowserModule], declarations: [MyComponent], bootstrap: [MyComponent]})
|
||||
export class AppModule {
|
||||
}
|
||||
|
||||
platformBrowserDynamic().bootstrapModule(AppModule);
|
||||
// #enddocregion
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load("//packages/bazel:index.bzl", "protractor_web_test_suite")
|
||||
load("//tools:defaults.bzl", "ng_module", "ts_library")
|
||||
load("@build_bazel_rules_typescript//:defs.bzl", "ts_devserver")
|
||||
|
||||
ng_module(
|
||||
name = "forms_examples",
|
||||
srcs = glob(
|
||||
["**/*.ts"],
|
||||
exclude = ["**/*_spec.ts"],
|
||||
),
|
||||
# TODO: FW-1004 Type checking is currently not complete.
|
||||
type_check = False,
|
||||
deps = [
|
||||
"//packages/core",
|
||||
"//packages/forms",
|
||||
"//packages/platform-browser",
|
||||
"//packages/platform-browser-dynamic",
|
||||
"//packages/router",
|
||||
],
|
||||
)
|
||||
|
||||
ts_library(
|
||||
name = "forms_e2e_tests_lib",
|
||||
testonly = True,
|
||||
srcs = glob(["**/e2e_test/*_spec.ts"]),
|
||||
tsconfig = "//packages/examples:tsconfig-e2e.json",
|
||||
deps = [
|
||||
"//packages/examples/test-utils",
|
||||
"//packages/private/testing",
|
||||
"@ngdeps//@types/jasminewd2",
|
||||
"@ngdeps//protractor",
|
||||
],
|
||||
)
|
||||
|
||||
ts_devserver(
|
||||
name = "devserver",
|
||||
entry_module = "@angular/examples/forms/main",
|
||||
index_html = "//packages/examples:index.html",
|
||||
port = 4200,
|
||||
scripts = ["@ngdeps//node_modules/tslib:tslib.js"],
|
||||
static_files = [
|
||||
"@ngdeps//node_modules/zone.js:dist/zone.js",
|
||||
],
|
||||
deps = [":forms_examples"],
|
||||
)
|
||||
|
||||
protractor_web_test_suite(
|
||||
name = "protractor_tests",
|
||||
data = ["//packages/bazel/src/protractor/utils"],
|
||||
on_prepare = ":start-server.js",
|
||||
server = ":devserver",
|
||||
deps = [
|
||||
":forms_e2e_tests_lib",
|
||||
"@ngdeps//protractor",
|
||||
"@ngdeps//selenium-webdriver",
|
||||
],
|
||||
)
|
|
@ -0,0 +1,12 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
|
||||
import {TestsAppModuleNgFactory} from './test_module.ngfactory';
|
||||
|
||||
platformBrowserDynamic().bootstrapModuleFactory(TestsAppModuleNgFactory);
|
|
@ -0,0 +1,17 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
const protractorUtils = require('@angular/bazel/protractor-utils');
|
||||
const protractor = require('protractor');
|
||||
|
||||
module.exports = async function(config) {
|
||||
const {port} = await protractorUtils.runServer(config.workspace, config.server, '-port', []);
|
||||
const serverUrl = `http://localhost:${port}`;
|
||||
|
||||
protractor.browser.baseUrl = serverUrl;
|
||||
};
|
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
import {Component, NgModule} from '@angular/core';
|
||||
import {RouterModule} from '@angular/router';
|
||||
|
||||
import * as formBuilderExample from './ts/formBuilder/module';
|
||||
import * as nestedFormArrayExample from './ts/nestedFormArray/module';
|
||||
import * as nestedFormGroupExample from './ts/nestedFormGroup/module';
|
||||
import * as ngModelGroupExample from './ts/ngModelGroup/module';
|
||||
import * as radioButtonsExample from './ts/radioButtons/module';
|
||||
import * as reactiveRadioButtonsExample from './ts/reactiveRadioButtons/module';
|
||||
import * as reactiveSelectControlExample from './ts/reactiveSelectControl/module';
|
||||
import * as selectControlExample from './ts/selectControl/module';
|
||||
import * as simpleFormExample from './ts/simpleForm/module';
|
||||
import * as simpleFormControlExample from './ts/simpleFormControl/module';
|
||||
import * as simpleFormGroupExample from './ts/simpleFormGroup/module';
|
||||
import * as simpleNgModelExample from './ts/simpleNgModel/module';
|
||||
|
||||
@Component({selector: 'example-app', template: '<router-outlet></router-outlet>'})
|
||||
export class TestsAppComponent {
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
formBuilderExample.AppModule, nestedFormArrayExample.AppModule,
|
||||
nestedFormGroupExample.AppModule, ngModelGroupExample.AppModule, radioButtonsExample.AppModule,
|
||||
reactiveRadioButtonsExample.AppModule, reactiveSelectControlExample.AppModule,
|
||||
selectControlExample.AppModule, simpleFormExample.AppModule, simpleFormControlExample.AppModule,
|
||||
simpleFormGroupExample.AppModule, simpleNgModelExample.AppModule,
|
||||
|
||||
// Router configuration so that the individual e2e tests can load their
|
||||
// app components.
|
||||
RouterModule.forRoot([
|
||||
{path: 'formBuilder', component: formBuilderExample.AppComponent},
|
||||
{path: 'nestedFormArray', component: nestedFormArrayExample.AppComponent},
|
||||
{path: 'nestedFormGroup', component: nestedFormGroupExample.AppComponent},
|
||||
{path: 'ngModelGroup', component: ngModelGroupExample.AppComponent},
|
||||
{path: 'radioButtons', component: radioButtonsExample.AppComponent},
|
||||
{path: 'reactiveRadioButtons', component: reactiveRadioButtonsExample.AppComponent},
|
||||
{path: 'reactiveSelectControl', component: reactiveSelectControlExample.AppComponent},
|
||||
{path: 'selectControl', component: selectControlExample.AppComponent},
|
||||
{path: 'simpleForm', component: simpleFormExample.AppComponent},
|
||||
{path: 'simpleFormControl', component: simpleFormControlExample.AppComponent},
|
||||
{path: 'simpleFormGroup', component: simpleFormGroupExample.AppComponent},
|
||||
{path: 'simpleNgModel', component: simpleNgModelExample.AppComponent}
|
||||
])
|
||||
],
|
||||
declarations: [TestsAppComponent],
|
||||
bootstrap: [TestsAppComponent]
|
||||
})
|
||||
export class TestsAppModule {
|
||||
}
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import {ElementArrayFinder, browser, by, element} from 'protractor';
|
||||
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
|
||||
import {verifyNoBrowserErrors} from '../../../../test-utils';
|
||||
|
||||
describe('formBuilder example', () => {
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
|
@ -15,7 +15,7 @@ describe('formBuilder example', () => {
|
|||
let paragraphs: ElementArrayFinder;
|
||||
|
||||
beforeEach(() => {
|
||||
browser.get('/forms/ts/formBuilder/index.html');
|
||||
browser.get('/formBuilder');
|
||||
inputs = element.all(by.css('input'));
|
||||
paragraphs = element.all(by.css('p'));
|
||||
});
|
||||
|
|
|
@ -9,12 +9,14 @@
|
|||
import {NgModule} from '@angular/core';
|
||||
import {ReactiveFormsModule} from '@angular/forms';
|
||||
import {BrowserModule} from '@angular/platform-browser';
|
||||
import {FormBuilderComp} from './form_builder_example';
|
||||
import {DisabledFormControlComponent, FormBuilderComp} from './form_builder_example';
|
||||
|
||||
@NgModule({
|
||||
imports: [BrowserModule, ReactiveFormsModule],
|
||||
declarations: [FormBuilderComp],
|
||||
declarations: [FormBuilderComp, DisabledFormControlComponent],
|
||||
bootstrap: [FormBuilderComp]
|
||||
})
|
||||
export class AppModule {
|
||||
}
|
||||
|
||||
export {FormBuilderComp as AppComponent};
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import {ElementArrayFinder, browser, by, element} from 'protractor';
|
||||
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
|
||||
import {verifyNoBrowserErrors} from '../../../../test-utils';
|
||||
|
||||
describe('nestedFormArray example', () => {
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
|
@ -15,7 +15,7 @@ describe('nestedFormArray example', () => {
|
|||
let buttons: ElementArrayFinder;
|
||||
|
||||
beforeEach(() => {
|
||||
browser.get('/forms/ts/nestedFormArray/index.html');
|
||||
browser.get('/nestedFormArray');
|
||||
inputs = element.all(by.css('input'));
|
||||
buttons = element.all(by.css('button'));
|
||||
});
|
||||
|
|
|
@ -18,3 +18,5 @@ import {NestedFormArray} from './nested_form_array_example';
|
|||
})
|
||||
export class AppModule {
|
||||
}
|
||||
|
||||
export {NestedFormArray as AppComponent};
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import {ElementFinder, browser, by, element} from 'protractor';
|
||||
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
|
||||
import {verifyNoBrowserErrors} from '../../../../test-utils';
|
||||
|
||||
describe('nestedFormGroup example', () => {
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
|
@ -16,7 +16,7 @@ describe('nestedFormGroup example', () => {
|
|||
let button: ElementFinder;
|
||||
|
||||
beforeEach(() => {
|
||||
browser.get('/forms/ts/nestedFormGroup/index.html');
|
||||
browser.get('/nestedFormGroup');
|
||||
firstInput = element(by.css('[formControlName="first"]'));
|
||||
lastInput = element(by.css('[formControlName="last"]'));
|
||||
button = element(by.css('button:not([type="submit"])'));
|
||||
|
|
|
@ -18,3 +18,5 @@ import {NestedFormGroupComp} from './nested_form_group_example';
|
|||
})
|
||||
export class AppModule {
|
||||
}
|
||||
|
||||
export {NestedFormGroupComp as AppComponent};
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import {ElementArrayFinder, browser, by, element} from 'protractor';
|
||||
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
|
||||
import {verifyNoBrowserErrors} from '../../../../test-utils';
|
||||
|
||||
describe('ngModelGroup example', () => {
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
|
@ -15,7 +15,7 @@ describe('ngModelGroup example', () => {
|
|||
let buttons: ElementArrayFinder;
|
||||
|
||||
beforeEach(() => {
|
||||
browser.get('/forms/ts/ngModelGroup/index.html');
|
||||
browser.get('/ngModelGroup');
|
||||
inputs = element.all(by.css('input'));
|
||||
buttons = element.all(by.css('button'));
|
||||
});
|
||||
|
|
|
@ -18,3 +18,5 @@ import {NgModelGroupComp} from './ng_model_group_example';
|
|||
})
|
||||
export class AppModule {
|
||||
}
|
||||
|
||||
export {NgModelGroupComp as AppComponent};
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import {ElementArrayFinder, browser, by, element} from 'protractor';
|
||||
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
|
||||
import {verifyNoBrowserErrors} from '../../../../test-utils';
|
||||
|
||||
describe('radioButtons example', () => {
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
|
@ -15,7 +15,7 @@ describe('radioButtons example', () => {
|
|||
let paragraphs: ElementArrayFinder;
|
||||
|
||||
beforeEach(() => {
|
||||
browser.get('/forms/ts/radioButtons/index.html');
|
||||
browser.get('/radioButtons');
|
||||
inputs = element.all(by.css('input'));
|
||||
paragraphs = element.all(by.css('p'));
|
||||
});
|
||||
|
|
|
@ -18,3 +18,5 @@ import {RadioButtonComp} from './radio_button_example';
|
|||
})
|
||||
export class AppModule {
|
||||
}
|
||||
|
||||
export {RadioButtonComp as AppComponent};
|
||||
|
|
|
@ -7,14 +7,14 @@
|
|||
*/
|
||||
|
||||
import {ElementArrayFinder, browser, by, element} from 'protractor';
|
||||
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
|
||||
import {verifyNoBrowserErrors} from '../../../../test-utils';
|
||||
|
||||
describe('radioButtons example', () => {
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
let inputs: ElementArrayFinder;
|
||||
|
||||
beforeEach(() => {
|
||||
browser.get('/forms/ts/reactiveRadioButtons/index.html');
|
||||
browser.get('/reactiveRadioButtons');
|
||||
inputs = element.all(by.css('input'));
|
||||
});
|
||||
|
||||
|
|
|
@ -18,3 +18,5 @@ import {ReactiveRadioButtonComp} from './reactive_radio_button_example';
|
|||
})
|
||||
export class AppModule {
|
||||
}
|
||||
|
||||
export {ReactiveRadioButtonComp as AppComponent};
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import {ElementArrayFinder, ElementFinder, browser, by, element} from 'protractor';
|
||||
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
|
||||
import {verifyNoBrowserErrors} from '../../../../test-utils';
|
||||
|
||||
describe('reactiveSelectControl example', () => {
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
|
@ -16,7 +16,7 @@ describe('reactiveSelectControl example', () => {
|
|||
let p: ElementFinder;
|
||||
|
||||
beforeEach(() => {
|
||||
browser.get('/forms/ts/reactiveSelectControl/index.html');
|
||||
browser.get('/reactiveSelectControl');
|
||||
select = element(by.css('select'));
|
||||
options = element.all(by.css('option'));
|
||||
p = element(by.css('p'));
|
||||
|
|
|
@ -18,3 +18,5 @@ import {ReactiveSelectComp} from './reactive_select_control_example';
|
|||
})
|
||||
export class AppModule {
|
||||
}
|
||||
|
||||
export {ReactiveSelectComp as AppComponent};
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import {ElementArrayFinder, ElementFinder, browser, by, element} from 'protractor';
|
||||
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
|
||||
import {verifyNoBrowserErrors} from '../../../../test-utils';
|
||||
|
||||
describe('selectControl example', () => {
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
|
@ -16,7 +16,7 @@ describe('selectControl example', () => {
|
|||
let p: ElementFinder;
|
||||
|
||||
beforeEach(() => {
|
||||
browser.get('/forms/ts/selectControl/index.html');
|
||||
browser.get('/selectControl');
|
||||
select = element(by.css('select'));
|
||||
options = element.all(by.css('option'));
|
||||
p = element(by.css('p'));
|
||||
|
|
|
@ -18,3 +18,5 @@ import {SelectControlComp} from './select_control_example';
|
|||
})
|
||||
export class AppModule {
|
||||
}
|
||||
|
||||
export {SelectControlComp as AppComponent};
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import {ElementArrayFinder, browser, by, element} from 'protractor';
|
||||
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
|
||||
import {verifyNoBrowserErrors} from '../../../../test-utils';
|
||||
|
||||
describe('simpleForm example', () => {
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
|
@ -15,7 +15,7 @@ describe('simpleForm example', () => {
|
|||
let paragraphs: ElementArrayFinder;
|
||||
|
||||
beforeEach(() => {
|
||||
browser.get('/forms/ts/simpleForm/index.html');
|
||||
browser.get('/simpleForm');
|
||||
inputs = element.all(by.css('input'));
|
||||
paragraphs = element.all(by.css('p'));
|
||||
});
|
||||
|
|
|
@ -18,3 +18,5 @@ import {SimpleFormComp} from './simple_form_example';
|
|||
})
|
||||
export class AppModule {
|
||||
}
|
||||
|
||||
export {SimpleFormComp as AppComponent};
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import {ElementFinder, browser, by, element} from 'protractor';
|
||||
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
|
||||
import {verifyNoBrowserErrors} from '../../../../test-utils';
|
||||
|
||||
describe('simpleFormControl example', () => {
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
|
@ -18,7 +18,7 @@ describe('simpleFormControl example', () => {
|
|||
let statusP: ElementFinder;
|
||||
|
||||
beforeEach(() => {
|
||||
browser.get('/forms/ts/simpleFormControl/index.html');
|
||||
browser.get('/simpleFormControl');
|
||||
input = element(by.css('input'));
|
||||
valueP = element(by.css('p:first-of-type'));
|
||||
statusP = element(by.css('p:last-of-type'));
|
||||
|
|
|
@ -18,3 +18,5 @@ import {SimpleFormControl} from './simple_form_control_example';
|
|||
})
|
||||
export class AppModule {
|
||||
}
|
||||
|
||||
export {SimpleFormControl as AppComponent};
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import {ElementFinder, browser, by, element} from 'protractor';
|
||||
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
|
||||
import {verifyNoBrowserErrors} from '../../../../test-utils';
|
||||
|
||||
describe('formControlName example', () => {
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
|
@ -17,7 +17,7 @@ describe('formControlName example', () => {
|
|||
let lastInput: ElementFinder;
|
||||
|
||||
beforeEach(() => {
|
||||
browser.get('/forms/ts/simpleFormGroup/index.html');
|
||||
browser.get('/simpleFormGroup');
|
||||
firstInput = element(by.css('[formControlName="first"]'));
|
||||
lastInput = element(by.css('[formControlName="last"]'));
|
||||
});
|
||||
|
|
|
@ -18,3 +18,5 @@ import {SimpleFormGroup} from './simple_form_group_example';
|
|||
})
|
||||
export class AppModule {
|
||||
}
|
||||
|
||||
export {SimpleFormGroup as AppComponent};
|
||||
|
|
|
@ -18,3 +18,5 @@ import {SimpleNgModelComp} from './simple_ng_model_example';
|
|||
})
|
||||
export class AppModule {
|
||||
}
|
||||
|
||||
export {SimpleNgModelComp as AppComponent};
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
|
@ -0,0 +1,15 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Angular Examples</title>
|
||||
<base href="/">
|
||||
|
||||
<!-- Prevent the browser from requesting any favicon. This could throw off the console
|
||||
output checks. -->
|
||||
<link rel="icon" href="data:,">
|
||||
</head>
|
||||
<body>
|
||||
<example-app>Loading...</example-app>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,14 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load("//tools:defaults.bzl", "ng_module")
|
||||
|
||||
ng_module(
|
||||
name = "platform_browser_examples",
|
||||
srcs = glob(["**/*.ts"]),
|
||||
deps = [
|
||||
"//packages/compiler",
|
||||
"//packages/core",
|
||||
"//packages/platform-browser",
|
||||
"//packages/platform-browser-dynamic",
|
||||
],
|
||||
)
|
|
@ -11,7 +11,7 @@ import {Component, NgModule} from '@angular/core';
|
|||
import {BrowserModule} from '@angular/platform-browser';
|
||||
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
|
||||
|
||||
@Component({selector: 'my-component'})
|
||||
@Component({selector: 'my-component', template: 'text'})
|
||||
class MyAppComponent {
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load("//tools:defaults.bzl", "ts_library")
|
||||
|
||||
ts_library(
|
||||
name = "test-utils",
|
||||
srcs = ["index.ts"],
|
||||
deps = [
|
||||
"@ngdeps//@types/selenium-webdriver",
|
||||
],
|
||||
)
|
|
@ -0,0 +1,43 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
/* tslint:disable:no-console */
|
||||
import {WebDriver, logging} from 'selenium-webdriver';
|
||||
|
||||
declare var browser: WebDriver;
|
||||
declare var expect: any;
|
||||
|
||||
// TODO (juliemr): remove this method once this becomes a protractor plugin
|
||||
export async function verifyNoBrowserErrors() {
|
||||
const browserLog = await browser.manage().logs().get('browser');
|
||||
const collectedErrors: any[] = [];
|
||||
|
||||
browserLog.forEach(logEntry => {
|
||||
const msg = logEntry.message;
|
||||
|
||||
// Since we currently use the `ts_devserver` from the Bazel TypeScript rules, which does
|
||||
// fallback to the "index.html" file for HTML5 pushState routing but does always serve the
|
||||
// expected fallback with a 404 status code, the browser will print a message about the 404,
|
||||
// while the page loaded properly. Ideally the "ts_devserver" would allow us to opt-in for
|
||||
// just returning a 200 status code, but the devserver is intended to be kept manually, so
|
||||
// we manually filter this error before ensuring there are no console errors.
|
||||
// TODO: This is a current limitation of using the "ts_devserver" with Angular routing.
|
||||
// Tracked with: TOOL-629
|
||||
if (msg.includes(
|
||||
`Failed to load resource: the server responded with a status of 404 (Not Found)`)) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('>> ' + msg, logEntry);
|
||||
|
||||
if (logEntry.level.value >= logging.Level.INFO.value) {
|
||||
collectedErrors.push(msg);
|
||||
}
|
||||
});
|
||||
|
||||
expect(collectedErrors).toEqual([]);
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -u -e -o pipefail
|
||||
|
||||
(
|
||||
cd `dirname $0`
|
||||
./build.sh
|
||||
|
||||
gulp serve-examples &
|
||||
trap "kill $!" EXIT
|
||||
|
||||
(
|
||||
cd ../../
|
||||
NODE_PATH=${NODE_PATH:-}:dist/all
|
||||
$(npm bin)/protractor protractor-examples-e2e.conf.js --bundles=true
|
||||
)
|
||||
)
|
|
@ -0,0 +1,13 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load("//tools:defaults.bzl", "ts_library")
|
||||
|
||||
ts_library(
|
||||
name = "testing_examples",
|
||||
srcs = glob(["**/*.ts"]),
|
||||
tsconfig = "//packages:tsconfig-test.json",
|
||||
deps = [
|
||||
"@ngdeps//@types/jasmine",
|
||||
"@ngdeps//@types/node",
|
||||
],
|
||||
)
|
|
@ -1,22 +0,0 @@
|
|||
{
|
||||
"extends": "../tsconfig-build.json",
|
||||
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"emitDecoratorMetadata": true,
|
||||
"baseUrl": ".",
|
||||
"rootDir": ".",
|
||||
"paths": {
|
||||
"@angular/*": ["../../dist/packages-dist/*"],
|
||||
"rxjs/*": ["../../node_modules/rxjs/*"]
|
||||
},
|
||||
"outDir": "../../dist/examples",
|
||||
"types": ["angular"]
|
||||
},
|
||||
|
||||
"include": [
|
||||
"../../node_modules/@types/jasminewd2/index.d.ts",
|
||||
"../types.d.ts",
|
||||
"**/*.ts"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"lib": ["es2015"],
|
||||
"types": ["node", "jasminewd2"]
|
||||
}
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
// WARNING:
|
||||
// This file is used to build the e2e tests only.
|
||||
// The rest of the files are included in `/packages/tsconfig.json`.
|
||||
{
|
||||
"extends": "../tsconfig.json",
|
||||
|
||||
"compilerOptions": {
|
||||
"types": []
|
||||
},
|
||||
|
||||
"include": [
|
||||
"../../node_modules/@types/jasminewd2/index.d.ts",
|
||||
"../types.d.ts",
|
||||
"**/e2e_test/*"
|
||||
],
|
||||
|
||||
"exclude": []
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
exports_files([
|
||||
"tsconfig-build.json",
|
||||
"start-server.js",
|
||||
])
|
|
@ -0,0 +1,17 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
const protractorUtils = require('@angular/bazel/protractor-utils');
|
||||
const protractor = require('protractor');
|
||||
|
||||
module.exports = async function(config) {
|
||||
const {port} = await protractorUtils.runServer(config.workspace, config.server, '-port', []);
|
||||
const serverUrl = `http://localhost:${port}`;
|
||||
|
||||
protractor.browser.baseUrl = serverUrl;
|
||||
};
|
|
@ -0,0 +1,14 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load("//packages/examples/upgrade:upgrade_example.bzl", "create_upgrade_example_targets")
|
||||
|
||||
create_upgrade_example_targets(
|
||||
name = "full",
|
||||
srcs = glob(
|
||||
["**/*.ts"],
|
||||
exclude = ["**/*_spec.ts"],
|
||||
),
|
||||
assets = ["styles.css"],
|
||||
e2e_srcs = glob(["e2e_test/*_spec.ts"]),
|
||||
entry_module = "@angular/examples/upgrade/static/ts/full/module",
|
||||
)
|
|
@ -7,11 +7,11 @@
|
|||
*/
|
||||
|
||||
import {browser, by, element} from 'protractor';
|
||||
import {verifyNoBrowserErrors} from '../../../../../_common/e2e_util';
|
||||
import {verifyNoBrowserErrors} from '../../../../../test-utils';
|
||||
|
||||
function loadPage() {
|
||||
browser.rootEl = 'example-app';
|
||||
browser.get('/upgrade/static/ts/full/');
|
||||
browser.get('/');
|
||||
}
|
||||
|
||||
describe('upgrade/static (full)', () => {
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load("//packages/examples/upgrade:upgrade_example.bzl", "create_upgrade_example_targets")
|
||||
|
||||
create_upgrade_example_targets(
|
||||
name = "lite-multi-shared",
|
||||
srcs = glob(
|
||||
["**/*.ts"],
|
||||
exclude = ["**/*_spec.ts"],
|
||||
),
|
||||
e2e_srcs = glob(["e2e_test/*_spec.ts"]),
|
||||
entry_module = "@angular/examples/upgrade/static/ts/lite-multi-shared/module",
|
||||
)
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
import {browser, by, element} from 'protractor';
|
||||
|
||||
import {verifyNoBrowserErrors} from '../../../../../_common/e2e_util';
|
||||
import {verifyNoBrowserErrors} from '../../../../../test-utils';
|
||||
|
||||
|
||||
describe('upgrade/static (lite with multiple downgraded modules and shared root module)', () => {
|
||||
|
@ -16,7 +16,7 @@ describe('upgrade/static (lite with multiple downgraded modules and shared root
|
|||
const compB = element(by.css('ng2-b'));
|
||||
const compC = element(by.css('ng2-c'));
|
||||
|
||||
beforeEach(() => browser.get('/upgrade/static/ts/lite-multi-shared/'));
|
||||
beforeEach(() => browser.get('/'));
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
|
||||
it('should share the same injectable instance across downgraded modules A and B', () => {
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load("//packages/examples/upgrade:upgrade_example.bzl", "create_upgrade_example_targets")
|
||||
|
||||
create_upgrade_example_targets(
|
||||
name = "lite-multi",
|
||||
srcs = glob(
|
||||
["**/*.ts"],
|
||||
exclude = ["**/*_spec.ts"],
|
||||
),
|
||||
e2e_srcs = glob(["e2e_test/*_spec.ts"]),
|
||||
entry_module = "@angular/examples/upgrade/static/ts/lite-multi/module",
|
||||
)
|
|
@ -8,14 +8,14 @@
|
|||
|
||||
import {browser, by, element} from 'protractor';
|
||||
|
||||
import {verifyNoBrowserErrors} from '../../../../../_common/e2e_util';
|
||||
import {verifyNoBrowserErrors} from '../../../../../test-utils';
|
||||
|
||||
|
||||
describe('upgrade/static (lite with multiple downgraded modules)', () => {
|
||||
const navButtons = element.all(by.css('nav button'));
|
||||
const mainContent = element(by.css('main'));
|
||||
|
||||
beforeEach(() => browser.get('/upgrade/static/ts/lite-multi/'));
|
||||
beforeEach(() => browser.get('/'));
|
||||
afterEach(verifyNoBrowserErrors);
|
||||
|
||||
it('should correctly bootstrap multiple downgraded modules', () => {
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
load("//packages/examples/upgrade:upgrade_example.bzl", "create_upgrade_example_targets")
|
||||
|
||||
create_upgrade_example_targets(
|
||||
name = "lite",
|
||||
srcs = glob(
|
||||
["**/*.ts"],
|
||||
exclude = ["e2e_test/*"],
|
||||
),
|
||||
assets = ["styles.css"],
|
||||
e2e_srcs = glob(["e2e_test/*.ts"]),
|
||||
entry_module = "@angular/examples/upgrade/static/ts/lite/module",
|
||||
)
|
|
@ -7,13 +7,13 @@
|
|||
*/
|
||||
|
||||
import {ElementArrayFinder, ElementFinder, browser, by, element} from 'protractor';
|
||||
import {verifyNoBrowserErrors} from '../../../../../test-utils';
|
||||
|
||||
import {verifyNoBrowserErrors} from '../../../../../_common/e2e_util';
|
||||
import {addCustomMatchers} from './e2e_util';
|
||||
|
||||
function loadPage() {
|
||||
browser.rootEl = 'example-app';
|
||||
browser.get('/upgrade/static/ts/lite/');
|
||||
browser.get('/');
|
||||
}
|
||||
|
||||
describe('upgrade/static (lite)', () => {
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"lib": ["dom", "es2015"],
|
||||
"types": ["angular"]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
load("//packages/bazel:index.bzl", "protractor_web_test_suite")
|
||||
load("//tools:defaults.bzl", "ng_module", "ts_library")
|
||||
load("@build_bazel_rules_typescript//:defs.bzl", "ts_devserver")
|
||||
|
||||
"""
|
||||
Macro that can be used to create the Bazel targets for an "upgrade" example. Since the
|
||||
upgrade examples bootstrap their application manually, and we cannot serve all examples,
|
||||
we need to define the devserver for each example. This macro reduces code duplication
|
||||
for defining these targets.
|
||||
"""
|
||||
|
||||
def create_upgrade_example_targets(name, srcs, e2e_srcs, entry_module, assets = []):
|
||||
ng_module(
|
||||
name = "%s_sources" % name,
|
||||
srcs = srcs,
|
||||
# TODO: FW-1004 Type checking is currently not complete.
|
||||
type_check = False,
|
||||
deps = [
|
||||
"@ngdeps//@types/angular",
|
||||
"//packages/core",
|
||||
"//packages/platform-browser",
|
||||
"//packages/platform-browser-dynamic",
|
||||
"//packages/upgrade/static",
|
||||
],
|
||||
tsconfig = "//packages/examples/upgrade:tsconfig-build.json",
|
||||
)
|
||||
|
||||
ts_library(
|
||||
name = "%s_e2e_lib" % name,
|
||||
srcs = e2e_srcs,
|
||||
testonly = True,
|
||||
deps = [
|
||||
"@ngdeps//@types/jasminewd2",
|
||||
"@ngdeps//protractor",
|
||||
"//packages/examples/test-utils",
|
||||
"//packages/private/testing",
|
||||
],
|
||||
tsconfig = "//packages/examples:tsconfig-e2e.json",
|
||||
)
|
||||
|
||||
ts_devserver(
|
||||
name = "devserver",
|
||||
port = 4200,
|
||||
entry_module = entry_module,
|
||||
static_files = [
|
||||
"@ngdeps//node_modules/zone.js:dist/zone.js",
|
||||
"@ngdeps//node_modules/angular:angular.js",
|
||||
"@ngdeps//node_modules/reflect-metadata:Reflect.js",
|
||||
],
|
||||
index_html = "//packages/examples:index.html",
|
||||
scripts = ["@ngdeps//node_modules/tslib:tslib.js"],
|
||||
deps = [":%s_sources" % name],
|
||||
data = assets,
|
||||
)
|
||||
|
||||
protractor_web_test_suite(
|
||||
name = "%s_protractor" % name,
|
||||
data = ["//packages/bazel/src/protractor/utils"],
|
||||
on_prepare = "//packages/examples/upgrade:start-server.js",
|
||||
server = ":devserver",
|
||||
deps = [
|
||||
":%s_e2e_lib" % name,
|
||||
"@ngdeps//protractor",
|
||||
"@ngdeps//selenium-webdriver",
|
||||
],
|
||||
)
|
|
@ -33,7 +33,12 @@
|
|||
"common/locales",
|
||||
"compiler-cli/integrationtest",
|
||||
"elements/schematics",
|
||||
// Do not build the example e2e spec files since those require custom typings and
|
||||
// aren't required to build all packages.
|
||||
"examples/**/e2e_test/*",
|
||||
// Exclude the "main.ts" files for each example group because this file is used by
|
||||
// Bazel to launch the devserver and uses AOT compilation.
|
||||
"examples/*/main.ts",
|
||||
"platform-server/integrationtest",
|
||||
"router/test/aot_ngsummary_test",
|
||||
]
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
// Make sure that the command line is read as the first thing
|
||||
// as this could exit node if the help script should be printed.
|
||||
require('./dist/all/e2e_util/e2e_util').readCommandLine();
|
||||
require('reflect-metadata');
|
||||
|
||||
Error.stackTraceLimit = 9999;
|
||||
|
||||
exports.config = {
|
||||
onPrepare: function() { beforeEach(function() { browser.ignoreSynchronization = false; }); },
|
||||
allScriptsTimeout: 11000,
|
||||
specs: ['dist/examples/**/e2e_test/*_spec.js'],
|
||||
capabilities: {
|
||||
'browserName': 'chrome',
|
||||
// Enables concurrent testing. Currently runs four e2e files in parallel.
|
||||
shardTestFiles: true,
|
||||
maxInstances: 4,
|
||||
},
|
||||
directConnect: true,
|
||||
baseUrl: 'http://localhost:8001/',
|
||||
framework: 'jasmine2',
|
||||
jasmineNodeOpts: {
|
||||
showColors: true,
|
||||
defaultTimeoutInterval: 60000,
|
||||
print: function(msg) { console.log(msg); },
|
||||
},
|
||||
useAllAngular2AppRoots: true
|
||||
};
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue