Skip to content

Commit 1ca34f9

Browse files
authored
chore(repo): split angular e2e tests into core and extensions (#6470)
1 parent f3b5ffc commit 1ca34f9

25 files changed

+1218
-1082
lines changed

.github/workflows/e2e-matrix.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ jobs:
3636
- yarn
3737
- pnpm
3838
packages:
39-
- e2e-angular
39+
- e2e-angular-core,e2e-angular-extensions
4040
- e2e-cli,e2e-nx-plugin,e2e-jest,e2e-linter
4141
- e2e-cypress
4242
- e2e-gatsby,e2e-react
@@ -104,7 +104,6 @@ jobs:
104104
NODE_OPTIONS: --max_old_space_size=8192
105105
SELECTED_PM: ${{ matrix.package_manager }}
106106
YARN_REGISTRY: http://localhost:4872
107-
SELECTED_CLI: ${{ matrix.packages == 'e2e-angular' && 'angular' || 'nx' }}
108107

109108
- name: Setup tmate session
110109
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled && failure() }}

e2e/angular/jest.config.js renamed to e2e/angular-core/jest.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ module.exports = {
66
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
77
maxWorkers: 1,
88
globals: { 'ts-jest': { tsconfig: '<rootDir>/tsconfig.spec.json' } },
9-
displayName: 'e2e-angular',
9+
displayName: 'e2e-angular-core',
1010
};

e2e/angular/project.json renamed to e2e/angular-core/project.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
2-
"root": "e2e/angular",
3-
"sourceRoot": "e2e/angular",
2+
"root": "e2e/angular-core",
3+
"sourceRoot": "e2e/angular-core",
44
"projectType": "application",
55
"targets": {
66
"e2e": {
@@ -14,7 +14,7 @@
1414
"command": "yarn e2e-build-package-publish"
1515
},
1616
{
17-
"command": "nx run-e2e-tests e2e-angular"
17+
"command": "nx run-e2e-tests e2e-angular-core"
1818
}
1919
],
2020
"parallel": false
@@ -23,11 +23,11 @@
2323
"run-e2e-tests": {
2424
"executor": "@nrwl/jest:jest",
2525
"options": {
26-
"jestConfig": "e2e/angular/jest.config.js",
26+
"jestConfig": "e2e/angular-core/jest.config.js",
2727
"passWithNoTests": true,
2828
"runInBand": true
2929
},
30-
"outputs": ["coverage/e2e/angular"]
30+
"outputs": ["coverage/e2e/angular-core"]
3131
}
3232
},
3333
"implicitDependencies": ["angular"]
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
import {
2+
checkFilesExist,
3+
expectTestsPass,
4+
getSelectedPackageManager,
5+
getSize,
6+
killPorts,
7+
newProject,
8+
removeProject,
9+
runCLI,
10+
runCLIAsync,
11+
tmpProjPath,
12+
uniq,
13+
updateFile,
14+
runCypressTests,
15+
} from '@nrwl/e2e/utils';
16+
17+
import { names } from '@nrwl/devkit';
18+
19+
describe('Angular Package', () => {
20+
describe('core', () => {
21+
let proj: string;
22+
23+
beforeEach(() => (proj = newProject()));
24+
afterEach(() => removeProject({ onlyOnCI: true }));
25+
26+
it('should work', async () => {
27+
// TODO: npm build is failing for Angular because of webpack 4
28+
// remove this condition once `node` is migrated to webpack 5
29+
if (getSelectedPackageManager() !== 'npm') {
30+
const myapp = uniq('myapp');
31+
const mylib = uniq('mylib');
32+
runCLI(
33+
`generate @nrwl/angular:app ${myapp} --directory=myDir --no-interactive`
34+
);
35+
runCLI(
36+
`generate @nrwl/angular:lib ${mylib} --directory=myDir --add-module-spec --no-interactive`
37+
);
38+
39+
updateFile(
40+
`apps/my-dir/${myapp}/src/app/app.module.ts`,
41+
`
42+
import { NgModule } from '@angular/core';
43+
import { BrowserModule } from '@angular/platform-browser';
44+
import { MyDir${
45+
names(mylib).className
46+
}Module } from '@${proj}/my-dir/${mylib}';
47+
import { AppComponent } from './app.component';
48+
49+
@NgModule({
50+
imports: [BrowserModule, MyDir${names(mylib).className}Module],
51+
declarations: [AppComponent],
52+
bootstrap: [AppComponent]
53+
})
54+
export class AppModule {}
55+
`
56+
);
57+
runCLI(`build my-dir-${myapp} --prod --output-hashing none`);
58+
59+
checkFilesExist(`dist/apps/my-dir/${myapp}/main.js`);
60+
61+
// This is a loose requirement because there are a lot of
62+
// influences external from this project that affect this.
63+
const es2015BundleSize = getSize(
64+
tmpProjPath(`dist/apps/my-dir/${myapp}/main.js`)
65+
);
66+
console.log(
67+
`The current es2015 bundle size is ${es2015BundleSize / 1000} KB`
68+
);
69+
expect(es2015BundleSize).toBeLessThanOrEqual(160000);
70+
71+
// running tests for the app
72+
expectTestsPass(await runCLIAsync(`test my-dir-${myapp} --no-watch`));
73+
74+
// running tests for the lib
75+
expectTestsPass(await runCLIAsync(`test my-dir-${mylib} --no-watch`));
76+
77+
if (runCypressTests()) {
78+
const e2eResults = runCLI(
79+
`e2e my-dir-${myapp}-e2e --headless --no-watch`
80+
);
81+
expect(e2eResults).toContain('All specs passed!');
82+
expect(await killPorts()).toBeTruthy();
83+
}
84+
}
85+
}, 1000000);
86+
87+
it('should support building in parallel', () => {
88+
// TODO: npm build is failing for Angular because of webpack 4
89+
// remove this condition once `node` is migrated to webpack 5
90+
if (getSelectedPackageManager() !== 'npm') {
91+
if (getSelectedPackageManager() === 'pnpm') {
92+
// TODO: This tests fails with pnpm but we should still enable this for other package managers
93+
return;
94+
}
95+
const myapp = uniq('myapp');
96+
const myapp2 = uniq('myapp');
97+
runCLI(`generate @nrwl/angular:app ${myapp}`);
98+
runCLI(`generate @nrwl/angular:app ${myapp2}`);
99+
100+
runCLI('run-many --target build --all --parallel');
101+
}
102+
});
103+
104+
it('should support Ivy', async () => {
105+
// TODO: npm build is failing for Angular because of webpack 4
106+
// remove this condition once `node` is migrated to webpack 5
107+
if (getSelectedPackageManager() !== 'npm') {
108+
const myapp = uniq('myapp');
109+
runCLI(
110+
`generate @nrwl/angular:app ${myapp} --directory=myDir --routing --enable-ivy`
111+
);
112+
113+
runCLI(`build my-dir-${myapp} --aot`);
114+
expectTestsPass(await runCLIAsync(`test my-dir-${myapp} --no-watch`));
115+
}
116+
}, 1000000);
117+
});
118+
});
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import {
2+
newProject,
3+
removeProject,
4+
runCLI,
5+
uniq,
6+
updateFile,
7+
} from '@nrwl/e2e/utils';
8+
import * as path from 'path';
9+
10+
describe('Angular Package', () => {
11+
describe('linting', () => {
12+
beforeEach(() => newProject());
13+
afterEach(() => removeProject({ onlyOnCI: true }));
14+
15+
it('should support eslint and pass linting on the standard generated code', async () => {
16+
const myapp = uniq('myapp');
17+
runCLI(`generate @nrwl/angular:app ${myapp} --linter=eslint`);
18+
expect(runCLI(`lint ${myapp}`)).toContain('All files pass linting.');
19+
20+
const mylib = uniq('mylib');
21+
runCLI(`generate @nrwl/angular:lib ${mylib} --linter=eslint`);
22+
expect(runCLI(`lint ${mylib}`)).toContain('All files pass linting.');
23+
});
24+
25+
it('should support eslint and successfully lint external HTML files and inline templates', async () => {
26+
const myapp = uniq('myapp');
27+
28+
runCLI(`generate @nrwl/angular:app ${myapp} --linter=eslint`);
29+
30+
const templateWhichFailsBananaInBoxLintCheck = `<div ([foo])="bar"></div>`;
31+
const wrappedAsInlineTemplate = `
32+
import { Component } from '@angular/core';
33+
34+
@Component({
35+
selector: 'inline-template-component',
36+
template: \`
37+
${templateWhichFailsBananaInBoxLintCheck}
38+
\`,
39+
})
40+
export class InlineTemplateComponent {}
41+
`;
42+
43+
// External HTML template file
44+
updateFile(
45+
`apps/${myapp}/src/app/app.component.html`,
46+
templateWhichFailsBananaInBoxLintCheck
47+
);
48+
49+
// Inline template within component.ts file
50+
updateFile(
51+
`apps/${myapp}/src/app/inline-template.component.ts`,
52+
wrappedAsInlineTemplate
53+
);
54+
55+
const appLintStdOut = runCLI(`lint ${myapp}`, { silenceError: true });
56+
expect(appLintStdOut).toContain(
57+
path.normalize(`apps/${myapp}/src/app/app.component.html`)
58+
);
59+
expect(appLintStdOut).toContain(`1:6`);
60+
expect(appLintStdOut).toContain(`Invalid binding syntax`);
61+
expect(appLintStdOut).toContain(
62+
path.normalize(`apps/${myapp}/src/app/inline-template.component.ts`)
63+
);
64+
expect(appLintStdOut).toContain(
65+
`The selector should start with one of these prefixes`
66+
);
67+
expect(appLintStdOut).toContain(`7:18`);
68+
});
69+
});
70+
});
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
process.env.SELECTED_CLI = 'angular';
2+
3+
import {
4+
expectTestsPass,
5+
newProject,
6+
readJson,
7+
removeProject,
8+
runCLI,
9+
runCLIAsync,
10+
uniq,
11+
updateFile,
12+
} from '@nrwl/e2e/utils';
13+
14+
describe('Angular Package', () => {
15+
describe('config compat', () => {
16+
beforeEach(() => newProject());
17+
afterEach(() => removeProject({ onlyOnCI: true }));
18+
19+
it('should work', async () => {
20+
const myapp = uniq('myapp');
21+
runCLI(`generate @nrwl/angular:app ${myapp} --no-interactive`);
22+
23+
// update the angular.json
24+
const workspaceJson = readJson(`angular.json`);
25+
workspaceJson.version = 2;
26+
workspaceJson.projects[myapp].targets = updateConfig(
27+
workspaceJson.projects[myapp].architect
28+
);
29+
workspaceJson.generators = workspaceJson.schematics;
30+
delete workspaceJson.schematics;
31+
updateFile('angular.json', JSON.stringify(workspaceJson, null, 2));
32+
33+
const myapp2 = uniq('myapp');
34+
runCLI(`generate @nrwl/angular:app ${myapp2} --no-interactive`);
35+
expectTestsPass(await runCLIAsync(`test ${myapp2} --no-watch`));
36+
}, 1000000);
37+
});
38+
});
39+
40+
function updateConfig(targets: any) {
41+
const res = {};
42+
Object.entries(targets).forEach(([name, t]: any) => {
43+
t.executor = t.builder;
44+
delete t.builder;
45+
res[name] = t;
46+
});
47+
return res;
48+
}

0 commit comments

Comments
 (0)