build: switch example e2e tests to bazel (#28402)

* No longer builds the example e2e tests using "tsc". The examples are now built with Bazel and can therefore be built with Ivy by using the `--define=compile=aot` switch.
* No longer runs the example e2e tests using the protractor CLI. example e2e tests are executed with the Bazel protractor rule and can therefore run incrementally.

NOTE: Unit tests found within the examples are still running within the legacy jobs.

PR Close #28402
This commit is contained in:
Paul Gschwendtner
2019-01-28 21:59:25 +01:00
committed by Jason Aden
parent 66335c36e6
commit 98e5af1480
103 changed files with 898 additions and 416 deletions

View File

@ -0,0 +1,59 @@
package(default_visibility = ["//visibility:public"])
load("//packages/bazel:index.bzl", "protractor_web_test_suite")
load("//tools:defaults.bzl", "ng_module", "ts_library")
load("@build_bazel_rules_typescript//:defs.bzl", "ts_devserver")
ng_module(
name = "forms_examples",
srcs = glob(
["**/*.ts"],
exclude = ["**/*_spec.ts"],
),
# TODO: FW-1004 Type checking is currently not complete.
type_check = False,
deps = [
"//packages/core",
"//packages/forms",
"//packages/platform-browser",
"//packages/platform-browser-dynamic",
"//packages/router",
],
)
ts_library(
name = "forms_e2e_tests_lib",
testonly = True,
srcs = glob(["**/e2e_test/*_spec.ts"]),
tsconfig = "//packages/examples:tsconfig-e2e.json",
deps = [
"//packages/examples/test-utils",
"//packages/private/testing",
"@ngdeps//@types/jasminewd2",
"@ngdeps//protractor",
],
)
ts_devserver(
name = "devserver",
entry_module = "@angular/examples/forms/main",
index_html = "//packages/examples:index.html",
port = 4200,
scripts = ["@ngdeps//node_modules/tslib:tslib.js"],
static_files = [
"@ngdeps//node_modules/zone.js:dist/zone.js",
],
deps = [":forms_examples"],
)
protractor_web_test_suite(
name = "protractor_tests",
data = ["//packages/bazel/src/protractor/utils"],
on_prepare = ":start-server.js",
server = ":devserver",
deps = [
":forms_e2e_tests_lib",
"@ngdeps//protractor",
"@ngdeps//selenium-webdriver",
],
)

View 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);

View 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;
};

View 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 {
}

View File

@ -7,7 +7,7 @@
*/
import {ElementArrayFinder, browser, by, element} from 'protractor';
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
import {verifyNoBrowserErrors} from '../../../../test-utils';
describe('formBuilder example', () => {
afterEach(verifyNoBrowserErrors);
@ -15,7 +15,7 @@ describe('formBuilder example', () => {
let paragraphs: ElementArrayFinder;
beforeEach(() => {
browser.get('/forms/ts/formBuilder/index.html');
browser.get('/formBuilder');
inputs = element.all(by.css('input'));
paragraphs = element.all(by.css('p'));
});

View File

@ -9,12 +9,14 @@
import {NgModule} from '@angular/core';
import {ReactiveFormsModule} from '@angular/forms';
import {BrowserModule} from '@angular/platform-browser';
import {FormBuilderComp} from './form_builder_example';
import {DisabledFormControlComponent, FormBuilderComp} from './form_builder_example';
@NgModule({
imports: [BrowserModule, ReactiveFormsModule],
declarations: [FormBuilderComp],
declarations: [FormBuilderComp, DisabledFormControlComponent],
bootstrap: [FormBuilderComp]
})
export class AppModule {
}
export {FormBuilderComp as AppComponent};

View File

@ -7,7 +7,7 @@
*/
import {ElementArrayFinder, browser, by, element} from 'protractor';
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
import {verifyNoBrowserErrors} from '../../../../test-utils';
describe('nestedFormArray example', () => {
afterEach(verifyNoBrowserErrors);
@ -15,7 +15,7 @@ describe('nestedFormArray example', () => {
let buttons: ElementArrayFinder;
beforeEach(() => {
browser.get('/forms/ts/nestedFormArray/index.html');
browser.get('/nestedFormArray');
inputs = element.all(by.css('input'));
buttons = element.all(by.css('button'));
});

View File

@ -18,3 +18,5 @@ import {NestedFormArray} from './nested_form_array_example';
})
export class AppModule {
}
export {NestedFormArray as AppComponent};

View File

@ -7,7 +7,7 @@
*/
import {ElementFinder, browser, by, element} from 'protractor';
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
import {verifyNoBrowserErrors} from '../../../../test-utils';
describe('nestedFormGroup example', () => {
afterEach(verifyNoBrowserErrors);
@ -16,7 +16,7 @@ describe('nestedFormGroup example', () => {
let button: ElementFinder;
beforeEach(() => {
browser.get('/forms/ts/nestedFormGroup/index.html');
browser.get('/nestedFormGroup');
firstInput = element(by.css('[formControlName="first"]'));
lastInput = element(by.css('[formControlName="last"]'));
button = element(by.css('button:not([type="submit"])'));

View File

@ -18,3 +18,5 @@ import {NestedFormGroupComp} from './nested_form_group_example';
})
export class AppModule {
}
export {NestedFormGroupComp as AppComponent};

View File

@ -7,7 +7,7 @@
*/
import {ElementArrayFinder, browser, by, element} from 'protractor';
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
import {verifyNoBrowserErrors} from '../../../../test-utils';
describe('ngModelGroup example', () => {
afterEach(verifyNoBrowserErrors);
@ -15,7 +15,7 @@ describe('ngModelGroup example', () => {
let buttons: ElementArrayFinder;
beforeEach(() => {
browser.get('/forms/ts/ngModelGroup/index.html');
browser.get('/ngModelGroup');
inputs = element.all(by.css('input'));
buttons = element.all(by.css('button'));
});

View File

@ -18,3 +18,5 @@ import {NgModelGroupComp} from './ng_model_group_example';
})
export class AppModule {
}
export {NgModelGroupComp as AppComponent};

View File

@ -7,7 +7,7 @@
*/
import {ElementArrayFinder, browser, by, element} from 'protractor';
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
import {verifyNoBrowserErrors} from '../../../../test-utils';
describe('radioButtons example', () => {
afterEach(verifyNoBrowserErrors);
@ -15,7 +15,7 @@ describe('radioButtons example', () => {
let paragraphs: ElementArrayFinder;
beforeEach(() => {
browser.get('/forms/ts/radioButtons/index.html');
browser.get('/radioButtons');
inputs = element.all(by.css('input'));
paragraphs = element.all(by.css('p'));
});

View File

@ -18,3 +18,5 @@ import {RadioButtonComp} from './radio_button_example';
})
export class AppModule {
}
export {RadioButtonComp as AppComponent};

View File

@ -7,14 +7,14 @@
*/
import {ElementArrayFinder, browser, by, element} from 'protractor';
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
import {verifyNoBrowserErrors} from '../../../../test-utils';
describe('radioButtons example', () => {
afterEach(verifyNoBrowserErrors);
let inputs: ElementArrayFinder;
beforeEach(() => {
browser.get('/forms/ts/reactiveRadioButtons/index.html');
browser.get('/reactiveRadioButtons');
inputs = element.all(by.css('input'));
});

View File

@ -18,3 +18,5 @@ import {ReactiveRadioButtonComp} from './reactive_radio_button_example';
})
export class AppModule {
}
export {ReactiveRadioButtonComp as AppComponent};

View File

@ -7,7 +7,7 @@
*/
import {ElementArrayFinder, ElementFinder, browser, by, element} from 'protractor';
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
import {verifyNoBrowserErrors} from '../../../../test-utils';
describe('reactiveSelectControl example', () => {
afterEach(verifyNoBrowserErrors);
@ -16,7 +16,7 @@ describe('reactiveSelectControl example', () => {
let p: ElementFinder;
beforeEach(() => {
browser.get('/forms/ts/reactiveSelectControl/index.html');
browser.get('/reactiveSelectControl');
select = element(by.css('select'));
options = element.all(by.css('option'));
p = element(by.css('p'));

View File

@ -18,3 +18,5 @@ import {ReactiveSelectComp} from './reactive_select_control_example';
})
export class AppModule {
}
export {ReactiveSelectComp as AppComponent};

View File

@ -7,7 +7,7 @@
*/
import {ElementArrayFinder, ElementFinder, browser, by, element} from 'protractor';
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
import {verifyNoBrowserErrors} from '../../../../test-utils';
describe('selectControl example', () => {
afterEach(verifyNoBrowserErrors);
@ -16,7 +16,7 @@ describe('selectControl example', () => {
let p: ElementFinder;
beforeEach(() => {
browser.get('/forms/ts/selectControl/index.html');
browser.get('/selectControl');
select = element(by.css('select'));
options = element.all(by.css('option'));
p = element(by.css('p'));

View File

@ -18,3 +18,5 @@ import {SelectControlComp} from './select_control_example';
})
export class AppModule {
}
export {SelectControlComp as AppComponent};

View File

@ -7,7 +7,7 @@
*/
import {ElementArrayFinder, browser, by, element} from 'protractor';
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
import {verifyNoBrowserErrors} from '../../../../test-utils';
describe('simpleForm example', () => {
afterEach(verifyNoBrowserErrors);
@ -15,7 +15,7 @@ describe('simpleForm example', () => {
let paragraphs: ElementArrayFinder;
beforeEach(() => {
browser.get('/forms/ts/simpleForm/index.html');
browser.get('/simpleForm');
inputs = element.all(by.css('input'));
paragraphs = element.all(by.css('p'));
});

View File

@ -18,3 +18,5 @@ import {SimpleFormComp} from './simple_form_example';
})
export class AppModule {
}
export {SimpleFormComp as AppComponent};

View File

@ -7,7 +7,7 @@
*/
import {ElementFinder, browser, by, element} from 'protractor';
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
import {verifyNoBrowserErrors} from '../../../../test-utils';
describe('simpleFormControl example', () => {
afterEach(verifyNoBrowserErrors);
@ -18,7 +18,7 @@ describe('simpleFormControl example', () => {
let statusP: ElementFinder;
beforeEach(() => {
browser.get('/forms/ts/simpleFormControl/index.html');
browser.get('/simpleFormControl');
input = element(by.css('input'));
valueP = element(by.css('p:first-of-type'));
statusP = element(by.css('p:last-of-type'));

View File

@ -18,3 +18,5 @@ import {SimpleFormControl} from './simple_form_control_example';
})
export class AppModule {
}
export {SimpleFormControl as AppComponent};

View File

@ -7,7 +7,7 @@
*/
import {ElementFinder, browser, by, element} from 'protractor';
import {verifyNoBrowserErrors} from '../../../../_common/e2e_util';
import {verifyNoBrowserErrors} from '../../../../test-utils';
describe('formControlName example', () => {
afterEach(verifyNoBrowserErrors);
@ -17,7 +17,7 @@ describe('formControlName example', () => {
let lastInput: ElementFinder;
beforeEach(() => {
browser.get('/forms/ts/simpleFormGroup/index.html');
browser.get('/simpleFormGroup');
firstInput = element(by.css('[formControlName="first"]'));
lastInput = element(by.css('[formControlName="last"]'));
});

View File

@ -18,3 +18,5 @@ import {SimpleFormGroup} from './simple_form_group_example';
})
export class AppModule {
}
export {SimpleFormGroup as AppComponent};

View File

@ -18,3 +18,5 @@ import {SimpleNgModelComp} from './simple_ng_model_example';
})
export class AppModule {
}
export {SimpleNgModelComp as AppComponent};