build: convert examples package to bazel (#28733)
* build: switch example e2e tests to bazel * 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. * test: disable failing ivy example e2e tests *Note for patch branch:* We had to disable more examples in Ivy because the patch branch does not contain all Ivy/ngtsc fixes.
This commit is contained in:
parent
b6dffa9763
commit
ac6b2b4dc3
2
.bazelrc
2
.bazelrc
@ -33,7 +33,7 @@ test:debug --test_arg=--node_options=--inspect-brk --test_output=streamed --test
|
|||||||
# eventually a surprising failure with auto-discovery of the C++ toolchain in
|
# eventually a surprising failure with auto-discovery of the C++ toolchain in
|
||||||
# MacOS High Sierra.
|
# MacOS High Sierra.
|
||||||
# See https://github.com/bazelbuild/bazel/issues/4603
|
# See https://github.com/bazelbuild/bazel/issues/4603
|
||||||
build --symlink_prefix=dist/
|
build --symlink_prefix=/
|
||||||
|
|
||||||
# Performance: avoid stat'ing input files
|
# Performance: avoid stat'ing input files
|
||||||
build --watchfs
|
build --watchfs
|
||||||
|
@ -491,7 +491,6 @@ jobs:
|
|||||||
- *download_yarn
|
- *download_yarn
|
||||||
- *yarn_install
|
- *yarn_install
|
||||||
- run: yarn tsc -p packages
|
- run: yarn tsc -p packages
|
||||||
- run: yarn tsc -p packages/examples
|
|
||||||
- run: yarn tsc -p modules
|
- run: yarn tsc -p modules
|
||||||
- run: yarn karma start ./karma-js.conf.js --single-run --browsers=ChromeNoSandbox
|
- run: yarn karma start ./karma-js.conf.js --single-run --browsers=ChromeNoSandbox
|
||||||
|
|
||||||
@ -518,7 +517,6 @@ jobs:
|
|||||||
command: ./scripts/saucelabs/start-tunnel.sh
|
command: ./scripts/saucelabs/start-tunnel.sh
|
||||||
background: true
|
background: true
|
||||||
- run: yarn tsc -p packages
|
- run: yarn tsc -p packages
|
||||||
- run: yarn tsc -p packages/examples
|
|
||||||
- run: yarn tsc -p modules
|
- run: yarn tsc -p modules
|
||||||
# Waits for the Saucelabs tunnel to be ready. This ensures that we don't run tests
|
# Waits for the Saucelabs tunnel to be ready. This ensures that we don't run tests
|
||||||
# too early without Saucelabs not being ready.
|
# too early without Saucelabs not being ready.
|
||||||
|
@ -53,7 +53,6 @@ gulp.task('source-map-test', loadTask('source-map-test'));
|
|||||||
gulp.task('tools:build', loadTask('tools-build'));
|
gulp.task('tools:build', loadTask('tools-build'));
|
||||||
gulp.task('check-cycle', loadTask('check-cycle'));
|
gulp.task('check-cycle', loadTask('check-cycle'));
|
||||||
gulp.task('serve', loadTask('serve', 'default'));
|
gulp.task('serve', loadTask('serve', 'default'));
|
||||||
gulp.task('serve-examples', loadTask('serve', 'examples'));
|
|
||||||
gulp.task('changelog', loadTask('changelog'));
|
gulp.task('changelog', loadTask('changelog'));
|
||||||
gulp.task('check-env', () => {/* this is a noop because the env test ran already above */});
|
gulp.task('check-env', () => {/* this is a noop because the env test ran already above */});
|
||||||
gulp.task('cldr:extract', loadTask('cldr', 'extract'));
|
gulp.task('cldr:extract', loadTask('cldr', 'extract'));
|
||||||
|
4
packages/examples/BUILD.bazel
Normal file
4
packages/examples/BUILD.bazel
Normal file
@ -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
|
# Running the examples
|
||||||
|
|
||||||
```
|
```
|
||||||
# # execute the following command only when framework code changes
|
# Serving individual examples (e.g. common)
|
||||||
./build.sh
|
yarn bazel run //packages/examples/common:devserver
|
||||||
|
|
||||||
# run when test change
|
# "core" examples
|
||||||
./packages/examples/build.sh
|
yarn bazel run //packages/examples/core:devserver
|
||||||
|
|
||||||
# start server
|
|
||||||
$(npm bin)/gulp serve-examples
|
|
||||||
```
|
```
|
||||||
|
|
||||||
navigate to [http://localhost:8001](http://localhost:8001)
|
|
||||||
|
|
||||||
# Running the tests
|
# Running the tests
|
||||||
|
|
||||||
```
|
```
|
||||||
# run only when framework code changes
|
yarn bazel test //packages/examples/...
|
||||||
./build.sh
|
|
||||||
|
|
||||||
# run to compile tests and run them
|
|
||||||
./packages/examples/test.sh
|
|
||||||
```
|
```
|
||||||
|
|
||||||
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>
|
|
19
packages/examples/_common/module.d.ts
vendored
19
packages/examples/_common/module.d.ts
vendored
@ -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
|
|
||||||
)
|
|
68
packages/examples/common/BUILD.bazel
Normal file
68
packages/examples/common/BUILD.bazel
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
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: This does not compile with Ivy because the patch branch does not contain
|
||||||
|
# all ngtsc fixes.
|
||||||
|
tags = ["fixme-ivy-aot"],
|
||||||
|
# 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",
|
||||||
|
],
|
||||||
|
tags = ["fixme-ivy-aot"],
|
||||||
|
deps = [":common_examples"],
|
||||||
|
)
|
||||||
|
|
||||||
|
protractor_web_test_suite(
|
||||||
|
name = "protractor_tests",
|
||||||
|
data = ["//packages/bazel/src/protractor/utils"],
|
||||||
|
on_prepare = ":start-server.js",
|
||||||
|
server = ":devserver",
|
||||||
|
tags = ["fixme-ivy-aot"],
|
||||||
|
deps = [
|
||||||
|
":common_tests_lib",
|
||||||
|
"@ngdeps//protractor",
|
||||||
|
"@ngdeps//selenium-webdriver",
|
||||||
|
],
|
||||||
|
)
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
import {$, browser, by, element, protractor} from 'protractor';
|
import {$, browser, by, element, protractor} from 'protractor';
|
||||||
|
|
||||||
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
|
import {verifyNoBrowserErrors} from '../../../../test-utils';
|
||||||
|
|
||||||
|
|
||||||
function waitForElement(selector: string) {
|
function waitForElement(selector: string) {
|
||||||
@ -21,10 +21,9 @@ describe('Location', () => {
|
|||||||
afterEach(verifyNoBrowserErrors);
|
afterEach(verifyNoBrowserErrors);
|
||||||
|
|
||||||
it('should verify paths', () => {
|
it('should verify paths', () => {
|
||||||
browser.get('/common/location/ts/#/bar/baz');
|
browser.get('/location/#/bar/baz');
|
||||||
waitForElement('hash-location');
|
waitForElement('hash-location');
|
||||||
expect(element.all(by.css('path-location code')).get(0).getText())
|
expect(element.all(by.css('path-location code')).get(0).getText()).toEqual('/location');
|
||||||
.toEqual('/common/location/ts');
|
|
||||||
expect(element.all(by.css('hash-location code')).get(0).getText()).toEqual('/bar/baz');
|
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',
|
selector: 'example-app',
|
||||||
template: `<hash-location></hash-location><path-location></path-location>`
|
template: `<hash-location></hash-location><path-location></path-location>`
|
||||||
})
|
})
|
||||||
export class ExampleAppComponent {
|
export class AppComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [ExampleAppComponent, PathLocationComponent, HashLocationComponent],
|
declarations: [AppComponent, PathLocationComponent, HashLocationComponent],
|
||||||
providers: [{provide: APP_BASE_HREF, useValue: '/'}],
|
providers: [{provide: APP_BASE_HREF, useValue: '/'}],
|
||||||
imports: [BrowserModule],
|
imports: [BrowserModule],
|
||||||
bootstrap: [ExampleAppComponent]
|
|
||||||
})
|
})
|
||||||
export class AppModule {
|
export class AppModule {
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,8 @@
|
|||||||
* Use of this source code is governed by an MIT-style license that can be
|
* 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
|
* 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) {
|
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
|
||||||
platformBrowserDynamic().bootstrapModule(mod.AppModule);
|
import {TestsAppModuleNgFactory} from './test_module.ngfactory';
|
||||||
}
|
|
||||||
|
platformBrowserDynamic().bootstrapModuleFactory(TestsAppModuleNgFactory);
|
@ -6,8 +6,10 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {fixmeIvy} from '@angular/private/testing';
|
||||||
import {$, ExpectedConditions, browser, by, element} from 'protractor';
|
import {$, ExpectedConditions, browser, by, element} from 'protractor';
|
||||||
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
|
|
||||||
|
import {verifyNoBrowserErrors} from '../../../../test-utils';
|
||||||
|
|
||||||
function waitForElement(selector: string) {
|
function waitForElement(selector: string) {
|
||||||
const EC = ExpectedConditions;
|
const EC = ExpectedConditions;
|
||||||
@ -15,8 +17,11 @@ function waitForElement(selector: string) {
|
|||||||
browser.wait(EC.presenceOf($(selector)), 20000);
|
browser.wait(EC.presenceOf($(selector)), 20000);
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('ngComponentOutlet', () => {
|
fixmeIvy(
|
||||||
const URL = 'common/ngComponentOutlet/ts/';
|
'unknown. Run "yarn bazel run packages/examples/common:devserver --define=compile=aot" ' +
|
||||||
|
'to debug')
|
||||||
|
.describe('ngComponentOutlet', () => {
|
||||||
|
const URL = '/ngComponentOutlet';
|
||||||
afterEach(verifyNoBrowserErrors);
|
afterEach(verifyNoBrowserErrors);
|
||||||
|
|
||||||
describe('ng-component-outlet-example', () => {
|
describe('ng-component-outlet-example', () => {
|
||||||
@ -29,7 +34,9 @@ describe('ngComponentOutlet', () => {
|
|||||||
it('should render complete', () => {
|
it('should render complete', () => {
|
||||||
browser.get(URL);
|
browser.get(URL);
|
||||||
waitForElement('ng-component-outlet-complete-example');
|
waitForElement('ng-component-outlet-complete-example');
|
||||||
expect(element.all(by.css('complete-component')).getText()).toEqual(['Complete: AhojSvet!']);
|
expect(element.all(by.css('complete-component')).getText()).toEqual([
|
||||||
|
'Complete: AhojSvet!'
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render other module', () => {
|
it('should render other module', () => {
|
||||||
@ -40,4 +47,4 @@ describe('ngComponentOutlet', () => {
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -7,21 +7,22 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {CommonModule} from '@angular/common';
|
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 {BrowserModule} from '@angular/platform-browser';
|
||||||
|
import {JitCompilerFactory} from '@angular/platform-browser-dynamic';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// #docregion SimpleExample
|
// #docregion SimpleExample
|
||||||
@Component({selector: 'hello-world', template: 'Hello World!'})
|
@Component({selector: 'hello-world', template: 'Hello World!'})
|
||||||
class HelloWorld {
|
export class HelloWorld {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ng-component-outlet-simple-example',
|
selector: 'ng-component-outlet-simple-example',
|
||||||
template: `<ng-container *ngComponentOutlet="HelloWorld"></ng-container>`
|
template: `<ng-container *ngComponentOutlet="HelloWorld"></ng-container>`
|
||||||
})
|
})
|
||||||
class NgTemplateOutletSimpleExample {
|
export class NgTemplateOutletSimpleExample {
|
||||||
// This field is necessary to expose HelloWorld to the template.
|
// This field is necessary to expose HelloWorld to the template.
|
||||||
HelloWorld = HelloWorld;
|
HelloWorld = HelloWorld;
|
||||||
}
|
}
|
||||||
@ -29,7 +30,7 @@ class NgTemplateOutletSimpleExample {
|
|||||||
|
|
||||||
// #docregion CompleteExample
|
// #docregion CompleteExample
|
||||||
@Injectable()
|
@Injectable()
|
||||||
class Greeter {
|
export class Greeter {
|
||||||
suffix = '!';
|
suffix = '!';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,7 +38,7 @@ class Greeter {
|
|||||||
selector: 'complete-component',
|
selector: 'complete-component',
|
||||||
template: `Complete: <ng-content></ng-content> <ng-content></ng-content>{{ greeter.suffix }}`
|
template: `Complete: <ng-content></ng-content> <ng-content></ng-content>{{ greeter.suffix }}`
|
||||||
})
|
})
|
||||||
class CompleteComponent {
|
export class CompleteComponent {
|
||||||
constructor(public greeter: Greeter) {}
|
constructor(public greeter: Greeter) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,7 +49,7 @@ class CompleteComponent {
|
|||||||
injector: myInjector;
|
injector: myInjector;
|
||||||
content: myContent"></ng-container>`
|
content: myContent"></ng-container>`
|
||||||
})
|
})
|
||||||
class NgTemplateOutletCompleteExample {
|
export class NgTemplateOutletCompleteExample {
|
||||||
// This field is necessary to expose CompleteComponent to the template.
|
// This field is necessary to expose CompleteComponent to the template.
|
||||||
CompleteComponent = CompleteComponent;
|
CompleteComponent = CompleteComponent;
|
||||||
myInjector: Injector;
|
myInjector: Injector;
|
||||||
@ -64,7 +65,7 @@ class NgTemplateOutletCompleteExample {
|
|||||||
|
|
||||||
// #docregion NgModuleFactoryExample
|
// #docregion NgModuleFactoryExample
|
||||||
@Component({selector: 'other-module-component', template: `Other Module Component!`})
|
@Component({selector: 'other-module-component', template: `Other Module Component!`})
|
||||||
class OtherModuleComponent {
|
export class OtherModuleComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -73,7 +74,7 @@ class OtherModuleComponent {
|
|||||||
<ng-container *ngComponentOutlet="OtherModuleComponent;
|
<ng-container *ngComponentOutlet="OtherModuleComponent;
|
||||||
ngModuleFactory: myModule;"></ng-container>`
|
ngModuleFactory: myModule;"></ng-container>`
|
||||||
})
|
})
|
||||||
class NgTemplateOutletOtherModuleExample {
|
export class NgTemplateOutletOtherModuleExample {
|
||||||
// This field is necessary to expose OtherModuleComponent to the template.
|
// This field is necessary to expose OtherModuleComponent to the template.
|
||||||
OtherModuleComponent = OtherModuleComponent;
|
OtherModuleComponent = OtherModuleComponent;
|
||||||
myModule: NgModuleFactory<any>;
|
myModule: NgModuleFactory<any>;
|
||||||
@ -91,19 +92,7 @@ class NgTemplateOutletOtherModuleExample {
|
|||||||
<hr/>
|
<hr/>
|
||||||
<ng-component-outlet-other-module-example></ng-component-outlet-other-module-example>`
|
<ng-component-outlet-other-module-example></ng-component-outlet-other-module-example>`
|
||||||
})
|
})
|
||||||
class ExampleApp {
|
export class AppComponent {
|
||||||
}
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
imports: [BrowserModule],
|
|
||||||
declarations: [
|
|
||||||
ExampleApp, NgTemplateOutletSimpleExample, NgTemplateOutletCompleteExample,
|
|
||||||
NgTemplateOutletOtherModuleExample, HelloWorld, CompleteComponent
|
|
||||||
],
|
|
||||||
entryComponents: [HelloWorld, CompleteComponent],
|
|
||||||
bootstrap: [ExampleApp]
|
|
||||||
})
|
|
||||||
export class AppModule {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
@ -113,3 +102,26 @@ export class AppModule {
|
|||||||
})
|
})
|
||||||
export class OtherModule {
|
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 {
|
||||||
|
}
|
||||||
|
@ -6,8 +6,9 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {fixmeIvy} from '@angular/private/testing';
|
||||||
import {$, ExpectedConditions, browser, by, element} from 'protractor';
|
import {$, ExpectedConditions, browser, by, element} from 'protractor';
|
||||||
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
|
import {verifyNoBrowserErrors} from '../../../../test-utils';
|
||||||
|
|
||||||
function waitForElement(selector: string) {
|
function waitForElement(selector: string) {
|
||||||
const EC = ExpectedConditions;
|
const EC = ExpectedConditions;
|
||||||
@ -16,7 +17,7 @@ function waitForElement(selector: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
describe('ngIf', () => {
|
describe('ngIf', () => {
|
||||||
const URL = 'common/ngIf/ts/';
|
const URL = '/ngIf';
|
||||||
afterEach(verifyNoBrowserErrors);
|
afterEach(verifyNoBrowserErrors);
|
||||||
|
|
||||||
describe('ng-if-simple', () => {
|
describe('ng-if-simple', () => {
|
||||||
@ -44,7 +45,9 @@ describe('ngIf', () => {
|
|||||||
|
|
||||||
describe('ng-if-then-else', () => {
|
describe('ng-if-then-else', () => {
|
||||||
let comp = 'ng-if-then-else';
|
let comp = 'ng-if-then-else';
|
||||||
it('should hide/show content', () => {
|
|
||||||
|
fixmeIvy('unknown. Run "yarn bazel run packages/examples/common:devserver" to debug')
|
||||||
|
.it('should hide/show content', () => {
|
||||||
browser.get(URL);
|
browser.get(URL);
|
||||||
waitForElement(comp);
|
waitForElement(comp);
|
||||||
expect(element.all(by.css(comp)).get(0).getText())
|
expect(element.all(by.css(comp)).get(0).getText())
|
||||||
@ -54,7 +57,8 @@ describe('ngIf', () => {
|
|||||||
.toEqual('hideSwitch Primary show = true\nSecondary text to show');
|
.toEqual('hideSwitch Primary show = true\nSecondary text to show');
|
||||||
element.all(by.css(comp + ' button')).get(0).click();
|
element.all(by.css(comp + ' button')).get(0).click();
|
||||||
expect(element.all(by.css(comp)).get(0).getText())
|
expect(element.all(by.css(comp)).get(0).getText())
|
||||||
.toEqual('showSwitch Primary show = false\nAlternate text while primary text is hidden');
|
.toEqual(
|
||||||
|
'showSwitch Primary show = false\nAlternate text while primary text is hidden');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ import {Subject} from 'rxjs';
|
|||||||
<div *ngIf="show">Text to show</div>
|
<div *ngIf="show">Text to show</div>
|
||||||
`
|
`
|
||||||
})
|
})
|
||||||
class NgIfSimple {
|
export class NgIfSimple {
|
||||||
show: boolean = true;
|
show: boolean = true;
|
||||||
}
|
}
|
||||||
// #enddocregion
|
// #enddocregion
|
||||||
@ -37,7 +37,7 @@ class NgIfSimple {
|
|||||||
<ng-template #elseBlock>Alternate text while primary text is hidden</ng-template>
|
<ng-template #elseBlock>Alternate text while primary text is hidden</ng-template>
|
||||||
`
|
`
|
||||||
})
|
})
|
||||||
class NgIfElse {
|
export class NgIfElse {
|
||||||
show: boolean = true;
|
show: boolean = true;
|
||||||
}
|
}
|
||||||
// #enddocregion
|
// #enddocregion
|
||||||
@ -56,7 +56,7 @@ class NgIfElse {
|
|||||||
<ng-template #elseBlock>Alternate text while primary text is hidden</ng-template>
|
<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;
|
thenBlock: TemplateRef<any>|null = null;
|
||||||
show: boolean = true;
|
show: boolean = true;
|
||||||
|
|
||||||
@ -85,7 +85,7 @@ class NgIfThenElse implements OnInit {
|
|||||||
<ng-template #loading let-user>Waiting... (user is {{user|json}})</ng-template>
|
<ng-template #loading let-user>Waiting... (user is {{user|json}})</ng-template>
|
||||||
`
|
`
|
||||||
})
|
})
|
||||||
class NgIfAs {
|
export class NgIfAs {
|
||||||
userObservable = new Subject<{first: string, last: string}>();
|
userObservable = new Subject<{first: string, last: string}>();
|
||||||
first = ['John', 'Mike', 'Mary', 'Bob'];
|
first = ['John', 'Mike', 'Mary', 'Bob'];
|
||||||
firstIndex = 0;
|
firstIndex = 0;
|
||||||
@ -116,13 +116,12 @@ class NgIfAs {
|
|||||||
<hr>
|
<hr>
|
||||||
`
|
`
|
||||||
})
|
})
|
||||||
class ExampleApp {
|
export class AppComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [BrowserModule],
|
imports: [BrowserModule],
|
||||||
declarations: [ExampleApp, NgIfSimple, NgIfElse, NgIfThenElse, NgIfAs],
|
declarations: [AppComponent, NgIfSimple, NgIfElse, NgIfThenElse, NgIfAs],
|
||||||
bootstrap: [ExampleApp]
|
|
||||||
})
|
})
|
||||||
export class AppModule {
|
export class AppModule {
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {$, ExpectedConditions, browser, by, element} from 'protractor';
|
import {$, ExpectedConditions, browser, by, element} from 'protractor';
|
||||||
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
|
import {verifyNoBrowserErrors} from '../../../../test-utils';
|
||||||
|
|
||||||
function waitForElement(selector: string) {
|
function waitForElement(selector: string) {
|
||||||
const EC = ExpectedConditions;
|
const EC = ExpectedConditions;
|
||||||
@ -16,7 +16,7 @@ function waitForElement(selector: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
describe('ngTemplateOutlet', () => {
|
describe('ngTemplateOutlet', () => {
|
||||||
const URL = 'common/ngTemplateOutlet/ts/';
|
const URL = '/ngTemplateOutlet';
|
||||||
afterEach(verifyNoBrowserErrors);
|
afterEach(verifyNoBrowserErrors);
|
||||||
|
|
||||||
describe('ng-template-outlet-example', () => {
|
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>
|
<ng-template #svk let-person="localSk"><span>Ahoj {{person}}!</span></ng-template>
|
||||||
`
|
`
|
||||||
})
|
})
|
||||||
class NgTemplateOutletExample {
|
export class NgTemplateOutletExample {
|
||||||
myContext = {$implicit: 'World', localSk: 'Svet'};
|
myContext = {$implicit: 'World', localSk: 'Svet'};
|
||||||
}
|
}
|
||||||
// #enddocregion
|
// #enddocregion
|
||||||
@ -36,13 +36,12 @@ class NgTemplateOutletExample {
|
|||||||
selector: 'example-app',
|
selector: 'example-app',
|
||||||
template: `<ng-template-outlet-example></ng-template-outlet-example>`
|
template: `<ng-template-outlet-example></ng-template-outlet-example>`
|
||||||
})
|
})
|
||||||
class ExampleApp {
|
export class AppComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [BrowserModule],
|
imports: [BrowserModule],
|
||||||
declarations: [ExampleApp, NgTemplateOutletExample],
|
declarations: [AppComponent, NgTemplateOutletExample],
|
||||||
bootstrap: [ExampleApp]
|
|
||||||
})
|
})
|
||||||
export class AppModule {
|
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
|
// protractor will not see us. Also we want to have this outside the docregion so as not to confuse
|
||||||
// the reader.
|
// the reader.
|
||||||
function setInterval(fn: Function, delay: number) {
|
function setInterval(fn: Function, delay: number) {
|
||||||
const zone = Zone.current;
|
const zone = (window as any)['Zone'].current;
|
||||||
let rootZone = zone;
|
let rootZone = zone;
|
||||||
while (rootZone.parent) {
|
while (rootZone.parent) {
|
||||||
rootZone = rootZone.parent;
|
rootZone = rootZone.parent;
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {$, ExpectedConditions, browser, by, element} from 'protractor';
|
import {$, ExpectedConditions, browser, by, element} from 'protractor';
|
||||||
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
|
import {verifyNoBrowserErrors} from '../../../../test-utils';
|
||||||
|
|
||||||
function waitForElement(selector: string) {
|
function waitForElement(selector: string) {
|
||||||
const EC = ExpectedConditions;
|
const EC = ExpectedConditions;
|
||||||
@ -17,7 +17,7 @@ function waitForElement(selector: string) {
|
|||||||
|
|
||||||
describe('pipe', () => {
|
describe('pipe', () => {
|
||||||
afterEach(verifyNoBrowserErrors);
|
afterEach(verifyNoBrowserErrors);
|
||||||
const URL = '/common/pipes/ts/';
|
const URL = '/pipes';
|
||||||
|
|
||||||
describe('async', () => {
|
describe('async', () => {
|
||||||
it('should resolve and display promise', () => {
|
it('should resolve and display promise', () => {
|
||||||
|
@ -59,19 +59,19 @@ import {TitleCasePipeComponent} from './titlecase_pipe';
|
|||||||
<keyvalue-pipe></keyvalue-pipe>
|
<keyvalue-pipe></keyvalue-pipe>
|
||||||
`
|
`
|
||||||
})
|
})
|
||||||
export class ExampleAppComponent {
|
export class AppComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
AsyncPromisePipeComponent, AsyncObservablePipeComponent, ExampleAppComponent, JsonPipeComponent,
|
AsyncPromisePipeComponent, AsyncObservablePipeComponent, AppComponent, JsonPipeComponent,
|
||||||
DatePipeComponent, DeprecatedDatePipeComponent, LowerUpperPipeComponent, TitleCasePipeComponent,
|
DatePipeComponent, DeprecatedDatePipeComponent, LowerUpperPipeComponent, TitleCasePipeComponent,
|
||||||
NumberPipeComponent, PercentPipeComponent, DeprecatedPercentPipeComponent,
|
NumberPipeComponent, DeprecatedNumberPipeComponent, PercentPipeComponent,
|
||||||
CurrencyPipeComponent, DeprecatedCurrencyPipeComponent, SlicePipeStringComponent,
|
DeprecatedPercentPipeComponent, CurrencyPipeComponent, DeprecatedCurrencyPipeComponent,
|
||||||
SlicePipeListComponent, I18nPluralPipeComponent, I18nSelectPipeComponent, KeyValuePipeComponent
|
SlicePipeStringComponent, SlicePipeListComponent, I18nPluralPipeComponent,
|
||||||
|
I18nSelectPipeComponent, KeyValuePipeComponent
|
||||||
],
|
],
|
||||||
imports: [BrowserModule],
|
imports: [BrowserModule],
|
||||||
bootstrap: [ExampleAppComponent]
|
|
||||||
})
|
})
|
||||||
export class AppModule {
|
export class AppModule {
|
||||||
}
|
}
|
||||||
|
17
packages/examples/common/start-server.js
Normal file
17
packages/examples/common/start-server.js
Normal file
@ -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;
|
||||||
|
};
|
41
packages/examples/common/test_module.ts
Normal file
41
packages/examples/common/test_module.ts
Normal file
@ -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 {
|
||||||
|
}
|
13
packages/examples/compiler/BUILD.bazel
Normal file
13
packages/examples/compiler/BUILD.bazel
Normal file
@ -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 {UrlResolver} from '@angular/compiler';
|
||||||
import {NgModule} from '@angular/core';
|
import {Component, NgModule} from '@angular/core';
|
||||||
import {BrowserModule} from '@angular/platform-browser';
|
import {BrowserModule} from '@angular/platform-browser';
|
||||||
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
|
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
|
||||||
|
|
||||||
let MyApp: any;
|
@Component({selector: 'my-app', template: 'empty'})
|
||||||
|
class MyApp {
|
||||||
|
}
|
||||||
|
|
||||||
// #docregion url_resolver
|
// #docregion url_resolver
|
||||||
class MyUrlResolver extends UrlResolver {
|
class MyUrlResolver extends UrlResolver {
|
||||||
|
68
packages/examples/core/BUILD.bazel
Normal file
68
packages/examples/core/BUILD.bazel
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
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: This does not compile with Ivy because the patch branch does not contain
|
||||||
|
# all ngtsc fixes.
|
||||||
|
tags = ["fixme-ivy-aot"],
|
||||||
|
# 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",
|
||||||
|
],
|
||||||
|
tags = ["fixme-ivy-aot"],
|
||||||
|
deps = [":core_examples"],
|
||||||
|
)
|
||||||
|
|
||||||
|
protractor_web_test_suite(
|
||||||
|
name = "protractor_tests",
|
||||||
|
data = ["//packages/bazel/src/protractor/utils"],
|
||||||
|
on_prepare = ":start-server.js",
|
||||||
|
server = ":devserver",
|
||||||
|
tags = ["fixme-ivy-aot"],
|
||||||
|
deps = [
|
||||||
|
":core_e2e_tests_lib",
|
||||||
|
"@ngdeps//protractor",
|
||||||
|
"@ngdeps//selenium-webdriver",
|
||||||
|
],
|
||||||
|
)
|
@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {$, ExpectedConditions, browser, by, element} from 'protractor';
|
import {$, ExpectedConditions, browser, by, element} from 'protractor';
|
||||||
import {verifyNoBrowserErrors} from '../../../../../_common/e2e_util';
|
import {verifyNoBrowserErrors} from '../../../../../test-utils';
|
||||||
|
|
||||||
function waitForElement(selector: string) {
|
function waitForElement(selector: string) {
|
||||||
const EC = ExpectedConditions;
|
const EC = ExpectedConditions;
|
||||||
@ -19,7 +19,7 @@ describe('animation example', () => {
|
|||||||
afterEach(verifyNoBrowserErrors);
|
afterEach(verifyNoBrowserErrors);
|
||||||
|
|
||||||
describe('index view', () => {
|
describe('index view', () => {
|
||||||
const URL = '/core/animation/ts/dsl/';
|
const URL = '/animation/dsl/';
|
||||||
|
|
||||||
it('should list out the current collection of items', () => {
|
it('should list out the current collection of items', () => {
|
||||||
browser.get(URL);
|
browser.get(URL);
|
||||||
|
@ -5,4 +5,5 @@
|
|||||||
* Use of this source code is governed by an MIT-style license that can be
|
* 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
|
* 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 {ElementFinder, browser, by, element} from 'protractor';
|
||||||
import {verifyNoBrowserErrors} from '../../../../../_common/e2e_util';
|
import {verifyNoBrowserErrors} from '../../../../../test-utils';
|
||||||
|
|
||||||
describe('contentChild example', () => {
|
describe('contentChild example', () => {
|
||||||
afterEach(verifyNoBrowserErrors);
|
afterEach(verifyNoBrowserErrors);
|
||||||
@ -15,7 +15,7 @@ describe('contentChild example', () => {
|
|||||||
let result: ElementFinder;
|
let result: ElementFinder;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
browser.get('/core/di/ts/contentChild/index.html');
|
browser.get('/di/contentChild');
|
||||||
button = element(by.css('button'));
|
button = element(by.css('button'));
|
||||||
result = element(by.css('div'));
|
result = element(by.css('div'));
|
||||||
});
|
});
|
||||||
|
@ -17,3 +17,5 @@ import {ContentChildComp, Pane, Tab} from './content_child_example';
|
|||||||
})
|
})
|
||||||
export class AppModule {
|
export class AppModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export {ContentChildComp as AppComponent};
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {ElementFinder, browser, by, element} from 'protractor';
|
import {ElementFinder, browser, by, element} from 'protractor';
|
||||||
import {verifyNoBrowserErrors} from '../../../../../_common/e2e_util';
|
import {verifyNoBrowserErrors} from '../../../../../test-utils';
|
||||||
|
|
||||||
describe('contentChildren example', () => {
|
describe('contentChildren example', () => {
|
||||||
afterEach(verifyNoBrowserErrors);
|
afterEach(verifyNoBrowserErrors);
|
||||||
@ -16,7 +16,7 @@ describe('contentChildren example', () => {
|
|||||||
let resultNested: ElementFinder;
|
let resultNested: ElementFinder;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
browser.get('/core/di/ts/contentChildren/index.html');
|
browser.get('/di/contentChildren');
|
||||||
button = element(by.css('button'));
|
button = element(by.css('button'));
|
||||||
resultTopLevel = element(by.css('.top-level'));
|
resultTopLevel = element(by.css('.top-level'));
|
||||||
resultNested = element(by.css('.nested'));
|
resultNested = element(by.css('.nested'));
|
||||||
|
@ -17,3 +17,5 @@ import {ContentChildrenComp, Pane, Tab} from './content_children_example';
|
|||||||
})
|
})
|
||||||
export class AppModule {
|
export class AppModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export {ContentChildrenComp as AppComponent};
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {ElementFinder, browser, by, element} from 'protractor';
|
import {ElementFinder, browser, by, element} from 'protractor';
|
||||||
import {verifyNoBrowserErrors} from '../../../../../_common/e2e_util';
|
import {verifyNoBrowserErrors} from '../../../../../test-utils';
|
||||||
|
|
||||||
describe('viewChild example', () => {
|
describe('viewChild example', () => {
|
||||||
afterEach(verifyNoBrowserErrors);
|
afterEach(verifyNoBrowserErrors);
|
||||||
@ -15,7 +15,7 @@ describe('viewChild example', () => {
|
|||||||
let result: ElementFinder;
|
let result: ElementFinder;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
browser.get('/core/di/ts/viewChild/index.html');
|
browser.get('/di/viewChild');
|
||||||
button = element(by.css('button'));
|
button = element(by.css('button'));
|
||||||
result = element(by.css('div'));
|
result = element(by.css('div'));
|
||||||
});
|
});
|
||||||
|
@ -15,3 +15,5 @@ import {Pane, ViewChildComp} from './view_child_example';
|
|||||||
{imports: [BrowserModule], declarations: [ViewChildComp, Pane], bootstrap: [ViewChildComp]})
|
{imports: [BrowserModule], declarations: [ViewChildComp, Pane], bootstrap: [ViewChildComp]})
|
||||||
export class AppModule {
|
export class AppModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export {ViewChildComp as AppComponent};
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
|
|
||||||
import {ElementFinder, browser, by, element} from 'protractor';
|
import {ElementFinder, browser, by, element} from 'protractor';
|
||||||
import {verifyNoBrowserErrors} from '../../../../../_common/e2e_util';
|
import {verifyNoBrowserErrors} from '../../../../../test-utils';
|
||||||
|
|
||||||
describe('viewChildren example', () => {
|
describe('viewChildren example', () => {
|
||||||
afterEach(verifyNoBrowserErrors);
|
afterEach(verifyNoBrowserErrors);
|
||||||
@ -16,7 +16,7 @@ describe('viewChildren example', () => {
|
|||||||
let result: ElementFinder;
|
let result: ElementFinder;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
browser.get('/core/di/ts/viewChildren/index.html');
|
browser.get('/di/viewChildren');
|
||||||
button = element(by.css('button'));
|
button = element(by.css('button'));
|
||||||
result = element(by.css('div'));
|
result = element(by.css('div'));
|
||||||
});
|
});
|
||||||
|
@ -18,3 +18,5 @@ import {Pane, ViewChildrenComp} from './view_children_example';
|
|||||||
})
|
})
|
||||||
export class AppModule {
|
export class AppModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export {ViewChildrenComp as AppComponent};
|
||||||
|
12
packages/examples/core/main.ts
Normal file
12
packages/examples/core/main.ts
Normal file
@ -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);
|
17
packages/examples/core/start-server.js
Normal file
17
packages/examples/core/start-server.js
Normal file
@ -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;
|
||||||
|
};
|
44
packages/examples/core/test_module.ts
Normal file
44
packages/examples/core/test_module.ts
Normal file
@ -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 {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', () => {
|
describe('testability example', () => {
|
||||||
afterEach(verifyNoBrowserErrors);
|
afterEach(verifyNoBrowserErrors);
|
||||||
|
|
||||||
describe('using task tracking', () => {
|
describe('using task tracking', () => {
|
||||||
const URL = '/core/testability/ts/whenStable/';
|
const URL = '/testability/whenStable/';
|
||||||
|
|
||||||
it('times out with a list of tasks', done => {
|
it('times out with a list of tasks', done => {
|
||||||
browser.get(URL);
|
browser.get(URL);
|
||||||
@ -22,7 +28,7 @@ describe('testability example', () => {
|
|||||||
// Script that runs in the browser and calls whenStable with a timeout.
|
// Script that runs in the browser and calls whenStable with a timeout.
|
||||||
let waitWithResultScript = function(done: any) {
|
let waitWithResultScript = function(done: any) {
|
||||||
let rootEl = document.querySelector('example-app');
|
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);
|
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
|
* 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
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
export {AppModule} from './testability_example';
|
export {AppModule, StableTestCmp as AppComponent} from './testability_example';
|
||||||
|
23
packages/examples/core/testing/ts/BUILD.bazel
Normal file
23
packages/examples/core/testing/ts/BUILD.bazel
Normal file
@ -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",
|
||||||
|
],
|
||||||
|
)
|
12
packages/examples/core/testing/ts/example_spec.ts
Normal file
12
packages/examples/core/testing/ts/example_spec.ts
Normal file
@ -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
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
/* tslint:disable:no-console */
|
/* tslint:disable:no-console */
|
||||||
import {Component, Directive, EventEmitter} from '@angular/core';
|
import {Component, Directive, EventEmitter, NgModule} from '@angular/core';
|
||||||
|
|
||||||
// #docregion component-input
|
// #docregion component-input
|
||||||
@Component({
|
@Component({
|
||||||
@ -64,3 +64,9 @@ export class MyOutputComponent {
|
|||||||
onEveryFiveSeconds() { console.log('five seconds'); }
|
onEveryFiveSeconds() { console.log('five seconds'); }
|
||||||
}
|
}
|
||||||
// #enddocregion component-output-interval
|
// #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';
|
import {MyComponent} from './my_component';
|
||||||
|
|
||||||
enableProdMode();
|
enableProdMode();
|
||||||
@NgModule({imports: [BrowserModule], bootstrap: [MyComponent]})
|
|
||||||
class AppModule {
|
@NgModule({imports: [BrowserModule], declarations: [MyComponent], bootstrap: [MyComponent]})
|
||||||
|
export class AppModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
platformBrowserDynamic().bootstrapModule(AppModule);
|
platformBrowserDynamic().bootstrapModule(AppModule);
|
||||||
// #enddocregion
|
// #enddocregion
|
||||||
|
64
packages/examples/forms/BUILD.bazel
Normal file
64
packages/examples/forms/BUILD.bazel
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
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: This does not compile with Ivy because the patch branch does not contain
|
||||||
|
# all ngtsc fixes.
|
||||||
|
tags = ["fixme-ivy-aot"],
|
||||||
|
# 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",
|
||||||
|
],
|
||||||
|
tags = ["fixme-ivy-aot"],
|
||||||
|
deps = [":forms_examples"],
|
||||||
|
)
|
||||||
|
|
||||||
|
protractor_web_test_suite(
|
||||||
|
name = "protractor_tests",
|
||||||
|
data = ["//packages/bazel/src/protractor/utils"],
|
||||||
|
on_prepare = ":start-server.js",
|
||||||
|
server = ":devserver",
|
||||||
|
tags = ["fixme-ivy-aot"],
|
||||||
|
deps = [
|
||||||
|
":forms_e2e_tests_lib",
|
||||||
|
"@ngdeps//protractor",
|
||||||
|
"@ngdeps//selenium-webdriver",
|
||||||
|
],
|
||||||
|
)
|
12
packages/examples/forms/main.ts
Normal file
12
packages/examples/forms/main.ts
Normal file
@ -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);
|
17
packages/examples/forms/start-server.js
Normal file
17
packages/examples/forms/start-server.js
Normal file
@ -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;
|
||||||
|
};
|
58
packages/examples/forms/test_module.ts
Normal file
58
packages/examples/forms/test_module.ts
Normal file
@ -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 {ElementArrayFinder, browser, by, element} from 'protractor';
|
||||||
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
|
import {verifyNoBrowserErrors} from '../../../../test-utils';
|
||||||
|
|
||||||
describe('formBuilder example', () => {
|
describe('formBuilder example', () => {
|
||||||
afterEach(verifyNoBrowserErrors);
|
afterEach(verifyNoBrowserErrors);
|
||||||
@ -15,7 +15,7 @@ describe('formBuilder example', () => {
|
|||||||
let paragraphs: ElementArrayFinder;
|
let paragraphs: ElementArrayFinder;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
browser.get('/forms/ts/formBuilder/index.html');
|
browser.get('/formBuilder');
|
||||||
inputs = element.all(by.css('input'));
|
inputs = element.all(by.css('input'));
|
||||||
paragraphs = element.all(by.css('p'));
|
paragraphs = element.all(by.css('p'));
|
||||||
});
|
});
|
||||||
|
@ -9,12 +9,14 @@
|
|||||||
import {NgModule} from '@angular/core';
|
import {NgModule} from '@angular/core';
|
||||||
import {ReactiveFormsModule} from '@angular/forms';
|
import {ReactiveFormsModule} from '@angular/forms';
|
||||||
import {BrowserModule} from '@angular/platform-browser';
|
import {BrowserModule} from '@angular/platform-browser';
|
||||||
import {FormBuilderComp} from './form_builder_example';
|
import {DisabledFormControlComponent, FormBuilderComp} from './form_builder_example';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [BrowserModule, ReactiveFormsModule],
|
imports: [BrowserModule, ReactiveFormsModule],
|
||||||
declarations: [FormBuilderComp],
|
declarations: [FormBuilderComp, DisabledFormControlComponent],
|
||||||
bootstrap: [FormBuilderComp]
|
bootstrap: [FormBuilderComp]
|
||||||
})
|
})
|
||||||
export class AppModule {
|
export class AppModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export {FormBuilderComp as AppComponent};
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {ElementArrayFinder, browser, by, element} from 'protractor';
|
import {ElementArrayFinder, browser, by, element} from 'protractor';
|
||||||
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
|
import {verifyNoBrowserErrors} from '../../../../test-utils';
|
||||||
|
|
||||||
describe('nestedFormArray example', () => {
|
describe('nestedFormArray example', () => {
|
||||||
afterEach(verifyNoBrowserErrors);
|
afterEach(verifyNoBrowserErrors);
|
||||||
@ -15,7 +15,7 @@ describe('nestedFormArray example', () => {
|
|||||||
let buttons: ElementArrayFinder;
|
let buttons: ElementArrayFinder;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
browser.get('/forms/ts/nestedFormArray/index.html');
|
browser.get('/nestedFormArray');
|
||||||
inputs = element.all(by.css('input'));
|
inputs = element.all(by.css('input'));
|
||||||
buttons = element.all(by.css('button'));
|
buttons = element.all(by.css('button'));
|
||||||
});
|
});
|
||||||
|
@ -18,3 +18,5 @@ import {NestedFormArray} from './nested_form_array_example';
|
|||||||
})
|
})
|
||||||
export class AppModule {
|
export class AppModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export {NestedFormArray as AppComponent};
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {ElementFinder, browser, by, element} from 'protractor';
|
import {ElementFinder, browser, by, element} from 'protractor';
|
||||||
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
|
import {verifyNoBrowserErrors} from '../../../../test-utils';
|
||||||
|
|
||||||
describe('nestedFormGroup example', () => {
|
describe('nestedFormGroup example', () => {
|
||||||
afterEach(verifyNoBrowserErrors);
|
afterEach(verifyNoBrowserErrors);
|
||||||
@ -16,7 +16,7 @@ describe('nestedFormGroup example', () => {
|
|||||||
let button: ElementFinder;
|
let button: ElementFinder;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
browser.get('/forms/ts/nestedFormGroup/index.html');
|
browser.get('/nestedFormGroup');
|
||||||
firstInput = element(by.css('[formControlName="first"]'));
|
firstInput = element(by.css('[formControlName="first"]'));
|
||||||
lastInput = element(by.css('[formControlName="last"]'));
|
lastInput = element(by.css('[formControlName="last"]'));
|
||||||
button = element(by.css('button:not([type="submit"])'));
|
button = element(by.css('button:not([type="submit"])'));
|
||||||
|
@ -18,3 +18,5 @@ import {NestedFormGroupComp} from './nested_form_group_example';
|
|||||||
})
|
})
|
||||||
export class AppModule {
|
export class AppModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export {NestedFormGroupComp as AppComponent};
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {ElementArrayFinder, browser, by, element} from 'protractor';
|
import {ElementArrayFinder, browser, by, element} from 'protractor';
|
||||||
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
|
import {verifyNoBrowserErrors} from '../../../../test-utils';
|
||||||
|
|
||||||
describe('ngModelGroup example', () => {
|
describe('ngModelGroup example', () => {
|
||||||
afterEach(verifyNoBrowserErrors);
|
afterEach(verifyNoBrowserErrors);
|
||||||
@ -15,7 +15,7 @@ describe('ngModelGroup example', () => {
|
|||||||
let buttons: ElementArrayFinder;
|
let buttons: ElementArrayFinder;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
browser.get('/forms/ts/ngModelGroup/index.html');
|
browser.get('/ngModelGroup');
|
||||||
inputs = element.all(by.css('input'));
|
inputs = element.all(by.css('input'));
|
||||||
buttons = element.all(by.css('button'));
|
buttons = element.all(by.css('button'));
|
||||||
});
|
});
|
||||||
|
@ -18,3 +18,5 @@ import {NgModelGroupComp} from './ng_model_group_example';
|
|||||||
})
|
})
|
||||||
export class AppModule {
|
export class AppModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export {NgModelGroupComp as AppComponent};
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {ElementArrayFinder, browser, by, element} from 'protractor';
|
import {ElementArrayFinder, browser, by, element} from 'protractor';
|
||||||
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
|
import {verifyNoBrowserErrors} from '../../../../test-utils';
|
||||||
|
|
||||||
describe('radioButtons example', () => {
|
describe('radioButtons example', () => {
|
||||||
afterEach(verifyNoBrowserErrors);
|
afterEach(verifyNoBrowserErrors);
|
||||||
@ -15,7 +15,7 @@ describe('radioButtons example', () => {
|
|||||||
let paragraphs: ElementArrayFinder;
|
let paragraphs: ElementArrayFinder;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
browser.get('/forms/ts/radioButtons/index.html');
|
browser.get('/radioButtons');
|
||||||
inputs = element.all(by.css('input'));
|
inputs = element.all(by.css('input'));
|
||||||
paragraphs = element.all(by.css('p'));
|
paragraphs = element.all(by.css('p'));
|
||||||
});
|
});
|
||||||
|
@ -18,3 +18,5 @@ import {RadioButtonComp} from './radio_button_example';
|
|||||||
})
|
})
|
||||||
export class AppModule {
|
export class AppModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export {RadioButtonComp as AppComponent};
|
||||||
|
@ -7,14 +7,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {ElementArrayFinder, browser, by, element} from 'protractor';
|
import {ElementArrayFinder, browser, by, element} from 'protractor';
|
||||||
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
|
import {verifyNoBrowserErrors} from '../../../../test-utils';
|
||||||
|
|
||||||
describe('radioButtons example', () => {
|
describe('radioButtons example', () => {
|
||||||
afterEach(verifyNoBrowserErrors);
|
afterEach(verifyNoBrowserErrors);
|
||||||
let inputs: ElementArrayFinder;
|
let inputs: ElementArrayFinder;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
browser.get('/forms/ts/reactiveRadioButtons/index.html');
|
browser.get('/reactiveRadioButtons');
|
||||||
inputs = element.all(by.css('input'));
|
inputs = element.all(by.css('input'));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -18,3 +18,5 @@ import {ReactiveRadioButtonComp} from './reactive_radio_button_example';
|
|||||||
})
|
})
|
||||||
export class AppModule {
|
export class AppModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export {ReactiveRadioButtonComp as AppComponent};
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {ElementArrayFinder, ElementFinder, browser, by, element} from 'protractor';
|
import {ElementArrayFinder, ElementFinder, browser, by, element} from 'protractor';
|
||||||
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
|
import {verifyNoBrowserErrors} from '../../../../test-utils';
|
||||||
|
|
||||||
describe('reactiveSelectControl example', () => {
|
describe('reactiveSelectControl example', () => {
|
||||||
afterEach(verifyNoBrowserErrors);
|
afterEach(verifyNoBrowserErrors);
|
||||||
@ -16,7 +16,7 @@ describe('reactiveSelectControl example', () => {
|
|||||||
let p: ElementFinder;
|
let p: ElementFinder;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
browser.get('/forms/ts/reactiveSelectControl/index.html');
|
browser.get('/reactiveSelectControl');
|
||||||
select = element(by.css('select'));
|
select = element(by.css('select'));
|
||||||
options = element.all(by.css('option'));
|
options = element.all(by.css('option'));
|
||||||
p = element(by.css('p'));
|
p = element(by.css('p'));
|
||||||
|
@ -18,3 +18,5 @@ import {ReactiveSelectComp} from './reactive_select_control_example';
|
|||||||
})
|
})
|
||||||
export class AppModule {
|
export class AppModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export {ReactiveSelectComp as AppComponent};
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {ElementArrayFinder, ElementFinder, browser, by, element} from 'protractor';
|
import {ElementArrayFinder, ElementFinder, browser, by, element} from 'protractor';
|
||||||
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
|
import {verifyNoBrowserErrors} from '../../../../test-utils';
|
||||||
|
|
||||||
describe('selectControl example', () => {
|
describe('selectControl example', () => {
|
||||||
afterEach(verifyNoBrowserErrors);
|
afterEach(verifyNoBrowserErrors);
|
||||||
@ -16,7 +16,7 @@ describe('selectControl example', () => {
|
|||||||
let p: ElementFinder;
|
let p: ElementFinder;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
browser.get('/forms/ts/selectControl/index.html');
|
browser.get('/selectControl');
|
||||||
select = element(by.css('select'));
|
select = element(by.css('select'));
|
||||||
options = element.all(by.css('option'));
|
options = element.all(by.css('option'));
|
||||||
p = element(by.css('p'));
|
p = element(by.css('p'));
|
||||||
|
@ -18,3 +18,5 @@ import {SelectControlComp} from './select_control_example';
|
|||||||
})
|
})
|
||||||
export class AppModule {
|
export class AppModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export {SelectControlComp as AppComponent};
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {ElementArrayFinder, browser, by, element} from 'protractor';
|
import {ElementArrayFinder, browser, by, element} from 'protractor';
|
||||||
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
|
import {verifyNoBrowserErrors} from '../../../../test-utils';
|
||||||
|
|
||||||
describe('simpleForm example', () => {
|
describe('simpleForm example', () => {
|
||||||
afterEach(verifyNoBrowserErrors);
|
afterEach(verifyNoBrowserErrors);
|
||||||
@ -15,7 +15,7 @@ describe('simpleForm example', () => {
|
|||||||
let paragraphs: ElementArrayFinder;
|
let paragraphs: ElementArrayFinder;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
browser.get('/forms/ts/simpleForm/index.html');
|
browser.get('/simpleForm');
|
||||||
inputs = element.all(by.css('input'));
|
inputs = element.all(by.css('input'));
|
||||||
paragraphs = element.all(by.css('p'));
|
paragraphs = element.all(by.css('p'));
|
||||||
});
|
});
|
||||||
|
@ -18,3 +18,5 @@ import {SimpleFormComp} from './simple_form_example';
|
|||||||
})
|
})
|
||||||
export class AppModule {
|
export class AppModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export {SimpleFormComp as AppComponent};
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {ElementFinder, browser, by, element} from 'protractor';
|
import {ElementFinder, browser, by, element} from 'protractor';
|
||||||
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
|
import {verifyNoBrowserErrors} from '../../../../test-utils';
|
||||||
|
|
||||||
describe('simpleFormControl example', () => {
|
describe('simpleFormControl example', () => {
|
||||||
afterEach(verifyNoBrowserErrors);
|
afterEach(verifyNoBrowserErrors);
|
||||||
@ -18,7 +18,7 @@ describe('simpleFormControl example', () => {
|
|||||||
let statusP: ElementFinder;
|
let statusP: ElementFinder;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
browser.get('/forms/ts/simpleFormControl/index.html');
|
browser.get('/simpleFormControl');
|
||||||
input = element(by.css('input'));
|
input = element(by.css('input'));
|
||||||
valueP = element(by.css('p:first-of-type'));
|
valueP = element(by.css('p:first-of-type'));
|
||||||
statusP = element(by.css('p:last-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 class AppModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export {SimpleFormControl as AppComponent};
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {ElementFinder, browser, by, element} from 'protractor';
|
import {ElementFinder, browser, by, element} from 'protractor';
|
||||||
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
|
import {verifyNoBrowserErrors} from '../../../../test-utils';
|
||||||
|
|
||||||
describe('formControlName example', () => {
|
describe('formControlName example', () => {
|
||||||
afterEach(verifyNoBrowserErrors);
|
afterEach(verifyNoBrowserErrors);
|
||||||
@ -17,7 +17,7 @@ describe('formControlName example', () => {
|
|||||||
let lastInput: ElementFinder;
|
let lastInput: ElementFinder;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
browser.get('/forms/ts/simpleFormGroup/index.html');
|
browser.get('/simpleFormGroup');
|
||||||
firstInput = element(by.css('[formControlName="first"]'));
|
firstInput = element(by.css('[formControlName="first"]'));
|
||||||
lastInput = element(by.css('[formControlName="last"]'));
|
lastInput = element(by.css('[formControlName="last"]'));
|
||||||
});
|
});
|
||||||
|
@ -18,3 +18,5 @@ import {SimpleFormGroup} from './simple_form_group_example';
|
|||||||
})
|
})
|
||||||
export class AppModule {
|
export class AppModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export {SimpleFormGroup as AppComponent};
|
||||||
|
@ -6,17 +6,22 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {fixmeIvy} from '@angular/private/testing';
|
||||||
import {ElementArrayFinder, ElementFinder, browser, by, element} from 'protractor';
|
import {ElementArrayFinder, ElementFinder, browser, by, element} from 'protractor';
|
||||||
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
|
|
||||||
|
|
||||||
describe('simpleNgModel example', () => {
|
import {verifyNoBrowserErrors} from '../../../../test-utils';
|
||||||
|
|
||||||
|
fixmeIvy(
|
||||||
|
'unkown; verifyNoBrowserErrors fails due to "ExpressionChangedAfterItHasBeenCheckedError"' +
|
||||||
|
'Debug by running "yarn bazel run //packages/examples/forms:devserver --define=compile=aot')
|
||||||
|
.describe('simpleNgModel example', () => {
|
||||||
afterEach(verifyNoBrowserErrors);
|
afterEach(verifyNoBrowserErrors);
|
||||||
let input: ElementFinder;
|
let input: ElementFinder;
|
||||||
let paragraphs: ElementArrayFinder;
|
let paragraphs: ElementArrayFinder;
|
||||||
let button: ElementFinder;
|
let button: ElementFinder;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
browser.get('/forms/ts/simpleNgModel/index.html');
|
browser.get('/simpleNgModel');
|
||||||
input = element(by.css('input'));
|
input = element(by.css('input'));
|
||||||
paragraphs = element.all(by.css('p'));
|
paragraphs = element.all(by.css('p'));
|
||||||
button = element(by.css('button'));
|
button = element(by.css('button'));
|
||||||
@ -42,4 +47,4 @@ describe('simpleNgModel example', () => {
|
|||||||
expect(input.getAttribute('value')).toEqual('Nancy');
|
expect(input.getAttribute('value')).toEqual('Nancy');
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -18,3 +18,5 @@ import {SimpleNgModelComp} from './simple_ng_model_example';
|
|||||||
})
|
})
|
||||||
export class AppModule {
|
export class AppModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export {SimpleNgModelComp as AppComponent};
|
||||||
|
1
packages/examples/http/BUILD.bazel
Normal file
1
packages/examples/http/BUILD.bazel
Normal file
@ -0,0 +1 @@
|
|||||||
|
package(default_visibility = ["//visibility:public"])
|
15
packages/examples/index.html
Normal file
15
packages/examples/index.html
Normal file
@ -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>
|
17
packages/examples/platform-browser/BUILD.bazel
Normal file
17
packages/examples/platform-browser/BUILD.bazel
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
|
load("//tools:defaults.bzl", "ng_module")
|
||||||
|
|
||||||
|
ng_module(
|
||||||
|
name = "platform_browser_examples",
|
||||||
|
srcs = glob(["**/*.ts"]),
|
||||||
|
# TODO: This does not compile with Ivy because the patch branch does not contain
|
||||||
|
# all ngtsc fixes.
|
||||||
|
tags = ["fixme-ivy-aot"],
|
||||||
|
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 {BrowserModule} from '@angular/platform-browser';
|
||||||
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
|
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
|
||||||
|
|
||||||
@Component({selector: 'my-component'})
|
@Component({selector: 'my-component', template: 'text'})
|
||||||
class MyAppComponent {
|
class MyAppComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
11
packages/examples/test-utils/BUILD.bazel
Normal file
11
packages/examples/test-utils/BUILD.bazel
Normal file
@ -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",
|
||||||
|
],
|
||||||
|
)
|
43
packages/examples/test-utils/index.ts
Normal file
43
packages/examples/test-utils/index.ts
Normal file
@ -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
|
|
||||||
)
|
|
||||||
)
|
|
13
packages/examples/testing/BUILD.bazel
Normal file
13
packages/examples/testing/BUILD.bazel
Normal file
@ -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"
|
|
||||||
]
|
|
||||||
}
|
|
6
packages/examples/tsconfig-e2e.json
Normal file
6
packages/examples/tsconfig-e2e.json
Normal file
@ -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": []
|
|
||||||
}
|
|
4
packages/examples/upgrade/BUILD.bazel
Normal file
4
packages/examples/upgrade/BUILD.bazel
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
exports_files([
|
||||||
|
"tsconfig-build.json",
|
||||||
|
"start-server.js",
|
||||||
|
])
|
17
packages/examples/upgrade/start-server.js
Normal file
17
packages/examples/upgrade/start-server.js
Normal file
@ -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;
|
||||||
|
};
|
14
packages/examples/upgrade/static/ts/full/BUILD.bazel
Normal file
14
packages/examples/upgrade/static/ts/full/BUILD.bazel
Normal file
@ -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",
|
||||||
|
)
|
@ -6,15 +6,17 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {fixmeIvy} from '@angular/private/testing';
|
||||||
import {browser, by, element} from 'protractor';
|
import {browser, by, element} from 'protractor';
|
||||||
import {verifyNoBrowserErrors} from '../../../../../_common/e2e_util';
|
import {verifyNoBrowserErrors} from '../../../../../test-utils';
|
||||||
|
|
||||||
function loadPage() {
|
function loadPage() {
|
||||||
browser.rootEl = 'example-app';
|
browser.rootEl = 'example-app';
|
||||||
browser.get('/upgrade/static/ts/full/');
|
browser.get('/');
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('upgrade/static (full)', () => {
|
fixmeIvy('Disabled because the patch branch does not contain all Ivy fixes.')
|
||||||
|
.describe('upgrade/static (full)', () => {
|
||||||
beforeEach(loadPage);
|
beforeEach(loadPage);
|
||||||
afterEach(verifyNoBrowserErrors);
|
afterEach(verifyNoBrowserErrors);
|
||||||
|
|
||||||
@ -28,7 +30,8 @@ describe('upgrade/static (full)', () => {
|
|||||||
expect(heroComponents.count()).toEqual(3);
|
expect(heroComponents.count()).toEqual(3);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add a new hero when the "Add Hero" button is pressed', () => {
|
fixmeIvy('unknown; <ng1Hero> component does not seem to render name & description')
|
||||||
|
.it('should add a new hero when the "Add Hero" button is pressed', () => {
|
||||||
const addHeroButton = element.all(by.css('button')).last();
|
const addHeroButton = element.all(by.css('button')).last();
|
||||||
expect(addHeroButton.getText()).toEqual('Add Hero');
|
expect(addHeroButton.getText()).toEqual('Add Hero');
|
||||||
addHeroButton.click();
|
addHeroButton.click();
|
||||||
@ -36,7 +39,8 @@ describe('upgrade/static (full)', () => {
|
|||||||
expect(heroComponents.last().element(by.css('h2')).getText()).toEqual('Kamala Khan');
|
expect(heroComponents.last().element(by.css('h2')).getText()).toEqual('Kamala Khan');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should remove a hero when the "Remove" button is pressed', () => {
|
fixmeIvy('unknown; <ng1Hero> component does not seem to render name & description')
|
||||||
|
.it('should remove a hero when the "Remove" button is pressed', () => {
|
||||||
let firstHero = element.all(by.css('ng1-hero')).get(0);
|
let firstHero = element.all(by.css('ng1-hero')).get(0);
|
||||||
expect(firstHero.element(by.css('h2')).getText()).toEqual('Superman');
|
expect(firstHero.element(by.css('h2')).getText()).toEqual('Superman');
|
||||||
|
|
||||||
@ -50,4 +54,4 @@ describe('upgrade/static (full)', () => {
|
|||||||
firstHero = element.all(by.css('ng1-hero')).get(0);
|
firstHero = element.all(by.css('ng1-hero')).get(0);
|
||||||
expect(firstHero.element(by.css('h2')).getText()).toEqual('Wonder Woman');
|
expect(firstHero.element(by.css('h2')).getText()).toEqual('Wonder Woman');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -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 {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)', () => {
|
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 compB = element(by.css('ng2-b'));
|
||||||
const compC = element(by.css('ng2-c'));
|
const compC = element(by.css('ng2-c'));
|
||||||
|
|
||||||
beforeEach(() => browser.get('/upgrade/static/ts/lite-multi-shared/'));
|
beforeEach(() => browser.get('/'));
|
||||||
afterEach(verifyNoBrowserErrors);
|
afterEach(verifyNoBrowserErrors);
|
||||||
|
|
||||||
it('should share the same injectable instance across downgraded modules A and B', () => {
|
it('should share the same injectable instance across downgraded modules A and B', () => {
|
||||||
|
13
packages/examples/upgrade/static/ts/lite-multi/BUILD.bazel
Normal file
13
packages/examples/upgrade/static/ts/lite-multi/BUILD.bazel
Normal file
@ -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 {browser, by, element} from 'protractor';
|
||||||
|
|
||||||
import {verifyNoBrowserErrors} from '../../../../../_common/e2e_util';
|
import {verifyNoBrowserErrors} from '../../../../../test-utils';
|
||||||
|
|
||||||
|
|
||||||
describe('upgrade/static (lite with multiple downgraded modules)', () => {
|
describe('upgrade/static (lite with multiple downgraded modules)', () => {
|
||||||
const navButtons = element.all(by.css('nav button'));
|
const navButtons = element.all(by.css('nav button'));
|
||||||
const mainContent = element(by.css('main'));
|
const mainContent = element(by.css('main'));
|
||||||
|
|
||||||
beforeEach(() => browser.get('/upgrade/static/ts/lite-multi/'));
|
beforeEach(() => browser.get('/'));
|
||||||
afterEach(verifyNoBrowserErrors);
|
afterEach(verifyNoBrowserErrors);
|
||||||
|
|
||||||
it('should correctly bootstrap multiple downgraded modules', () => {
|
it('should correctly bootstrap multiple downgraded modules', () => {
|
||||||
|
14
packages/examples/upgrade/static/ts/lite/BUILD.bazel
Normal file
14
packages/examples/upgrade/static/ts/lite/BUILD.bazel
Normal file
@ -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",
|
||||||
|
)
|
@ -6,14 +6,15 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {fixmeIvy} from '@angular/private/testing';
|
||||||
import {ElementArrayFinder, ElementFinder, browser, by, element} from 'protractor';
|
import {ElementArrayFinder, ElementFinder, browser, by, element} from 'protractor';
|
||||||
|
import {verifyNoBrowserErrors} from '../../../../../test-utils';
|
||||||
|
|
||||||
import {verifyNoBrowserErrors} from '../../../../../_common/e2e_util';
|
|
||||||
import {addCustomMatchers} from './e2e_util';
|
import {addCustomMatchers} from './e2e_util';
|
||||||
|
|
||||||
function loadPage() {
|
function loadPage() {
|
||||||
browser.rootEl = 'example-app';
|
browser.rootEl = 'example-app';
|
||||||
browser.get('/upgrade/static/ts/lite/');
|
browser.get('/');
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('upgrade/static (lite)', () => {
|
describe('upgrade/static (lite)', () => {
|
||||||
@ -58,7 +59,8 @@ describe('upgrade/static (lite)', () => {
|
|||||||
|
|
||||||
it('should initially not render the heroes', () => expectHeroes(false));
|
it('should initially not render the heroes', () => expectHeroes(false));
|
||||||
|
|
||||||
it('should toggle the heroes when clicking the "show/hide" button', () => {
|
fixmeIvy('unknown; <ng1Hero> component does not seem to render name & description')
|
||||||
|
.it('should toggle the heroes when clicking the "show/hide" button', () => {
|
||||||
showHideBtn.click();
|
showHideBtn.click();
|
||||||
expectHeroes(true);
|
expectHeroes(true);
|
||||||
|
|
||||||
@ -66,7 +68,8 @@ describe('upgrade/static (lite)', () => {
|
|||||||
expectHeroes(false);
|
expectHeroes(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add a new hero when clicking the "add" button', () => {
|
fixmeIvy('unknown; <ng1Hero> component does not seem to render name & description')
|
||||||
|
.it('should add a new hero when clicking the "add" button', () => {
|
||||||
showHideBtn.click();
|
showHideBtn.click();
|
||||||
ng2HeroesAddBtn.click();
|
ng2HeroesAddBtn.click();
|
||||||
|
|
||||||
@ -74,7 +77,8 @@ describe('upgrade/static (lite)', () => {
|
|||||||
expect(ng1Heroes.last()).toHaveName('Kamala Khan');
|
expect(ng1Heroes.last()).toHaveName('Kamala Khan');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should remove a hero when clicking its "remove" button', () => {
|
fixmeIvy('unknown; <ng1Hero> component does not seem to render name & description')
|
||||||
|
.it('should remove a hero when clicking its "remove" button', () => {
|
||||||
showHideBtn.click();
|
showHideBtn.click();
|
||||||
|
|
||||||
const firstHero = ng1Heroes.first();
|
const firstHero = ng1Heroes.first();
|
||||||
|
6
packages/examples/upgrade/tsconfig-build.json
Normal file
6
packages/examples/upgrade/tsconfig-build.json
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"lib": ["dom", "es2015"],
|
||||||
|
"types": ["angular"]
|
||||||
|
}
|
||||||
|
}
|
66
packages/examples/upgrade/upgrade_example.bzl
Normal file
66
packages/examples/upgrade/upgrade_example.bzl
Normal file
@ -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",
|
"common/locales",
|
||||||
"compiler-cli/integrationtest",
|
"compiler-cli/integrationtest",
|
||||||
"elements/schematics",
|
"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/*",
|
"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",
|
"platform-server/integrationtest",
|
||||||
"router/test/aot_ngsummary_test",
|
"router/test/aot_ngsummary_test",
|
||||||
]
|
]
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user