chore(ng-schematics): Update ng e2e
to custom builder (#9300)
**What kind of change does this PR introduce?** This replaces the default `ng e2e` with our custom builder. In the feature it seem possible to remove the necessity of the user running the server separately and run it from the builder - that will improve the easy of use and CI of this schematic. **Did you add tests for your changes?** **If relevant, did you update the documentation?** Yes - Updated `@puppeteer/ng-schematics` README.md **Summary** We want to not see the default `ng e2e` and we want to make it easier for the user to run commands. Angular Developer are likely to also use its' CLI. **Does this PR introduce a breaking change?** Yes. Users need to delete the default and initialize the schematics again. **Other information**
This commit is contained in:
parent
0107ad8f08
commit
16784fc8cb
105
package-lock.json
generated
105
package-lock.json
generated
@ -80,6 +80,58 @@
|
|||||||
"zod": "3.19.1"
|
"zod": "3.19.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@angular-devkit/architect": {
|
||||||
|
"version": "0.1402.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1402.10.tgz",
|
||||||
|
"integrity": "sha512-/6YmPrgataj1jD2Uqd1ED+CG4DaZGacoeZd/89hH7hF76Nno8K18DrSOqJAEmDnOWegpSRGVLd0qP09IHmaG5w==",
|
||||||
|
"dependencies": {
|
||||||
|
"@angular-devkit/core": "14.2.10",
|
||||||
|
"rxjs": "6.6.7"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^14.15.0 || >=16.10.0",
|
||||||
|
"npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
|
||||||
|
"yarn": ">= 1.13.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@angular-devkit/architect/node_modules/@angular-devkit/core": {
|
||||||
|
"version": "14.2.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.10.tgz",
|
||||||
|
"integrity": "sha512-K4AO7mROTdbhQ7chtyQd6oPwmuL+BPUh+wn6Aq1qrmYJK4UZYFOPp8fi/Ehs8meCEeywtrssOPfrOE4Gsre9dg==",
|
||||||
|
"dependencies": {
|
||||||
|
"ajv": "8.11.0",
|
||||||
|
"ajv-formats": "2.1.1",
|
||||||
|
"jsonc-parser": "3.1.0",
|
||||||
|
"rxjs": "6.6.7",
|
||||||
|
"source-map": "0.7.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^14.15.0 || >=16.10.0",
|
||||||
|
"npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
|
||||||
|
"yarn": ">= 1.13.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"chokidar": "^3.5.2"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"chokidar": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@angular-devkit/architect/node_modules/jsonc-parser": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-DRf0QjnNeCUds3xTjKlQQ3DpJD51GvDjJfnxUVWg6PZTo2otSm+slzNAxU/35hF8/oJIKoG9slq30JYOsF2azg=="
|
||||||
|
},
|
||||||
|
"node_modules/@angular-devkit/architect/node_modules/source-map": {
|
||||||
|
"version": "0.7.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
|
||||||
|
"integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@angular-devkit/core": {
|
"node_modules/@angular-devkit/core": {
|
||||||
"version": "14.2.7",
|
"version": "14.2.7",
|
||||||
"resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.7.tgz",
|
"resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.7.tgz",
|
||||||
@ -8703,6 +8755,7 @@
|
|||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@angular-devkit/architect": "^0.1402.10",
|
||||||
"@angular-devkit/core": "^14.2.6",
|
"@angular-devkit/core": "^14.2.6",
|
||||||
"@angular-devkit/schematics": "^14.2.6"
|
"@angular-devkit/schematics": "^14.2.6"
|
||||||
},
|
},
|
||||||
@ -8755,24 +8808,6 @@
|
|||||||
"node": ">=14.1.0"
|
"node": ">=14.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"packages/puppeteer-schematics": {
|
|
||||||
"version": "0.0.0",
|
|
||||||
"extraneous": true,
|
|
||||||
"license": "Apache-2.0",
|
|
||||||
"dependencies": {
|
|
||||||
"@angular-devkit/architect": "0.1402.7",
|
|
||||||
"@angular-devkit/core": "^14.2.6",
|
|
||||||
"@angular-devkit/schematics": "^14.2.6",
|
|
||||||
"@schematics/angular": "^14.2.8",
|
|
||||||
"typescript": "~4.7.2"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@types/node": "^14.15.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=14.1.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"packages/testserver": {
|
"packages/testserver": {
|
||||||
"name": "@pptr/testserver",
|
"name": "@pptr/testserver",
|
||||||
"version": "0.6.0",
|
"version": "0.6.0",
|
||||||
@ -8799,6 +8834,39 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@angular-devkit/architect": {
|
||||||
|
"version": "0.1402.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1402.10.tgz",
|
||||||
|
"integrity": "sha512-/6YmPrgataj1jD2Uqd1ED+CG4DaZGacoeZd/89hH7hF76Nno8K18DrSOqJAEmDnOWegpSRGVLd0qP09IHmaG5w==",
|
||||||
|
"requires": {
|
||||||
|
"@angular-devkit/core": "14.2.10",
|
||||||
|
"rxjs": "6.6.7"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@angular-devkit/core": {
|
||||||
|
"version": "14.2.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.10.tgz",
|
||||||
|
"integrity": "sha512-K4AO7mROTdbhQ7chtyQd6oPwmuL+BPUh+wn6Aq1qrmYJK4UZYFOPp8fi/Ehs8meCEeywtrssOPfrOE4Gsre9dg==",
|
||||||
|
"requires": {
|
||||||
|
"ajv": "8.11.0",
|
||||||
|
"ajv-formats": "2.1.1",
|
||||||
|
"jsonc-parser": "3.1.0",
|
||||||
|
"rxjs": "6.6.7",
|
||||||
|
"source-map": "0.7.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"jsonc-parser": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-DRf0QjnNeCUds3xTjKlQQ3DpJD51GvDjJfnxUVWg6PZTo2otSm+slzNAxU/35hF8/oJIKoG9slq30JYOsF2azg=="
|
||||||
|
},
|
||||||
|
"source-map": {
|
||||||
|
"version": "0.7.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
|
||||||
|
"integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"@angular-devkit/core": {
|
"@angular-devkit/core": {
|
||||||
"version": "14.2.7",
|
"version": "14.2.7",
|
||||||
"resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.7.tgz",
|
"resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-14.2.7.tgz",
|
||||||
@ -9876,6 +9944,7 @@
|
|||||||
"@puppeteer/ng-schematics": {
|
"@puppeteer/ng-schematics": {
|
||||||
"version": "file:packages/ng-schematics",
|
"version": "file:packages/ng-schematics",
|
||||||
"requires": {
|
"requires": {
|
||||||
|
"@angular-devkit/architect": "^0.1402.10",
|
||||||
"@angular-devkit/core": "^14.2.6",
|
"@angular-devkit/core": "^14.2.6",
|
||||||
"@angular-devkit/schematics": "^14.2.6",
|
"@angular-devkit/schematics": "^14.2.6",
|
||||||
"@schematics/angular": "^14.2.8",
|
"@schematics/angular": "^14.2.8",
|
||||||
|
@ -20,13 +20,14 @@ Currently, this schematic supports the following test frameworks:
|
|||||||
- **Mocha** [https://mochajs.org/]
|
- **Mocha** [https://mochajs.org/]
|
||||||
- **Node Test Runner** _(Experimental)_ [https://nodejs.org/api/test.html]
|
- **Node Test Runner** _(Experimental)_ [https://nodejs.org/api/test.html]
|
||||||
|
|
||||||
With the schematics installed, you can run E2E tests:
|
With the schematics installed you can run E2E tests:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run e2e
|
ng e2e
|
||||||
# or yarn e2e
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
> Note: Server must be running before executing the command.
|
||||||
|
|
||||||
## Options
|
## Options
|
||||||
|
|
||||||
When adding schematics to your project you can to provide following options:
|
When adding schematics to your project you can to provide following options:
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
"node": ">=14.1.0"
|
"node": ">=14.1.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@angular-devkit/architect": "^0.1402.10",
|
||||||
"@angular-devkit/core": "^14.2.6",
|
"@angular-devkit/core": "^14.2.6",
|
||||||
"@angular-devkit/schematics": "^14.2.6"
|
"@angular-devkit/schematics": "^14.2.6"
|
||||||
},
|
},
|
||||||
@ -40,5 +41,6 @@
|
|||||||
"ng-add": {
|
"ng-add": {
|
||||||
"save": "devDependencies"
|
"save": "devDependencies"
|
||||||
},
|
},
|
||||||
"schematics": "./lib/schematics/collection.json"
|
"schematics": "./lib/schematics/collection.json",
|
||||||
|
"builders": "./lib/builders/builders.json"
|
||||||
}
|
}
|
||||||
|
10
packages/ng-schematics/src/builders/builders.json
Normal file
10
packages/ng-schematics/src/builders/builders.json
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"$schema": "../../../../node_modules/@angular-devkit/architect/src/builders-schema.json",
|
||||||
|
"builders": {
|
||||||
|
"puppeteer": {
|
||||||
|
"implementation": "./puppeteer",
|
||||||
|
"schema": "./puppeteer/schema.json",
|
||||||
|
"description": "Run e2e test with Puppeteer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
82
packages/ng-schematics/src/builders/puppeteer/index.ts
Normal file
82
packages/ng-schematics/src/builders/puppeteer/index.ts
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
import {
|
||||||
|
createBuilder,
|
||||||
|
BuilderContext,
|
||||||
|
BuilderOutput,
|
||||||
|
} from '@angular-devkit/architect';
|
||||||
|
import {spawn} from 'child_process';
|
||||||
|
|
||||||
|
import {PuppeteerBuilderOptions} from './types.js';
|
||||||
|
|
||||||
|
function getError(executable: string, args: string[]) {
|
||||||
|
return (
|
||||||
|
`Puppeteer E2E tests failed!` +
|
||||||
|
'\n' +
|
||||||
|
`Error running '${executable}' with arguments '${args.join(' ')}'.` +
|
||||||
|
`\n` +
|
||||||
|
'Please look at the output above to determine the issue!'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getExecutable(command: string[]) {
|
||||||
|
const executable = command.shift()!;
|
||||||
|
const error = getError(executable, command);
|
||||||
|
|
||||||
|
if (executable === 'node') {
|
||||||
|
return {
|
||||||
|
executable: executable,
|
||||||
|
args: command,
|
||||||
|
error,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
executable: `./node_modules/.bin/${executable}`,
|
||||||
|
args: command,
|
||||||
|
error,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function executeCommand(context: BuilderContext, command: string[]) {
|
||||||
|
await new Promise((resolve, reject) => {
|
||||||
|
const {executable, args, error} = getExecutable(command);
|
||||||
|
|
||||||
|
const child = spawn(executable, args, {
|
||||||
|
cwd: context.workspaceRoot,
|
||||||
|
stdio: 'inherit',
|
||||||
|
});
|
||||||
|
|
||||||
|
child.on('error', message => {
|
||||||
|
console.log(message);
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
|
||||||
|
child.on('exit', code => {
|
||||||
|
if (code === 0) {
|
||||||
|
resolve(true);
|
||||||
|
} else {
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function executeE2ETest(
|
||||||
|
options: PuppeteerBuilderOptions,
|
||||||
|
context: BuilderContext
|
||||||
|
): Promise<BuilderOutput> {
|
||||||
|
context.logger.debug('Running commands for E2E test.');
|
||||||
|
try {
|
||||||
|
for (const command of options.commands) {
|
||||||
|
await executeCommand(context, command);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {success: true};
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof Error) {
|
||||||
|
return {success: false, error: error.message};
|
||||||
|
}
|
||||||
|
return {success: false, error: error as any};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default createBuilder<PuppeteerBuilderOptions>(executeE2ETest) as any;
|
18
packages/ng-schematics/src/builders/puppeteer/schema.json
Normal file
18
packages/ng-schematics/src/builders/puppeteer/schema.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"title": "Puppeteer",
|
||||||
|
"description": "Options for Puppeteer Angular Schematics",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"commands": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "array",
|
||||||
|
"item": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"description": "Commands to execute in the repo. Commands prefixed with `./node_modules/bin` (Exception: 'node')."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": true
|
||||||
|
}
|
23
packages/ng-schematics/src/builders/puppeteer/types.ts
Normal file
23
packages/ng-schematics/src/builders/puppeteer/types.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2022 Google Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {JsonObject} from '@angular-devkit/core';
|
||||||
|
|
||||||
|
type Command = [string, ...string[]];
|
||||||
|
|
||||||
|
export interface PuppeteerBuilderOptions extends JsonObject {
|
||||||
|
commands: Command[];
|
||||||
|
}
|
@ -7,7 +7,7 @@
|
|||||||
<% } %><% if(testingFramework == 'node') { %>
|
<% } %><% if(testingFramework == 'node') { %>
|
||||||
"module": "CommonJS",
|
"module": "CommonJS",
|
||||||
"rootDir": "tests/",
|
"rootDir": "tests/",
|
||||||
"outDir": "out-tsc/",
|
"outDir": "test/",
|
||||||
<% } %>
|
<% } %>
|
||||||
"types": ["<%= testingFramework %>"]
|
"types": ["<%= testingFramework %>"]
|
||||||
},
|
},
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
# Compiled e2e tests output
|
# Compiled e2e tests output Node auto resolves files in folders named 'test'
|
||||||
|
|
||||||
/out-tsc
|
test/
|
@ -31,6 +31,7 @@ import {
|
|||||||
getPackageLatestNpmVersion,
|
getPackageLatestNpmVersion,
|
||||||
DependencyType,
|
DependencyType,
|
||||||
type NodePackage,
|
type NodePackage,
|
||||||
|
updateAngularJsonScripts,
|
||||||
} from '../utils/packages.js';
|
} from '../utils/packages.js';
|
||||||
|
|
||||||
import {type SchematicsOptions} from '../utils/types.js';
|
import {type SchematicsOptions} from '../utils/types.js';
|
||||||
@ -45,6 +46,7 @@ export function ngAdd(options: SchematicsOptions): Rule {
|
|||||||
addPuppeteerFiles(options),
|
addPuppeteerFiles(options),
|
||||||
addOtherFiles(options),
|
addOtherFiles(options),
|
||||||
updateScripts(options),
|
updateScripts(options),
|
||||||
|
updateAngularConfig(options),
|
||||||
])(tree, context);
|
])(tree, context);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -73,15 +75,14 @@ function addDependencies(options: SchematicsOptions): Rule {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateScripts(options: SchematicsOptions): Rule {
|
function updateScripts(_options: SchematicsOptions): Rule {
|
||||||
return (tree: Tree, context: SchematicContext): Tree => {
|
return (tree: Tree, context: SchematicContext): Tree => {
|
||||||
context.logger.debug('Updating "package.json" scripts');
|
context.logger.debug('Updating "package.json" scripts');
|
||||||
const script = getScriptFromOptions(options);
|
|
||||||
|
|
||||||
return addPackageJsonScripts(tree, [
|
return addPackageJsonScripts(tree, [
|
||||||
{
|
{
|
||||||
name: 'e2e',
|
name: 'e2e',
|
||||||
script,
|
script: 'ng e2e',
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
@ -89,7 +90,7 @@ function updateScripts(options: SchematicsOptions): Rule {
|
|||||||
|
|
||||||
function addPuppeteerFiles(options: SchematicsOptions): Rule {
|
function addPuppeteerFiles(options: SchematicsOptions): Rule {
|
||||||
return (tree: Tree, context: SchematicContext) => {
|
return (tree: Tree, context: SchematicContext) => {
|
||||||
context.logger.debug('Adding Puppeteer base files');
|
context.logger.debug('Adding Puppeteer base files.');
|
||||||
const {projects} = getAngularConfig(tree);
|
const {projects} = getAngularConfig(tree);
|
||||||
|
|
||||||
return addBaseFiles(tree, context, {
|
return addBaseFiles(tree, context, {
|
||||||
@ -101,7 +102,7 @@ function addPuppeteerFiles(options: SchematicsOptions): Rule {
|
|||||||
|
|
||||||
function addOtherFiles(options: SchematicsOptions): Rule {
|
function addOtherFiles(options: SchematicsOptions): Rule {
|
||||||
return (tree: Tree, context: SchematicContext) => {
|
return (tree: Tree, context: SchematicContext) => {
|
||||||
context.logger.debug('Adding Puppeteer additional files');
|
context.logger.debug('Adding Puppeteer additional files.');
|
||||||
const {projects} = getAngularConfig(tree);
|
const {projects} = getAngularConfig(tree);
|
||||||
|
|
||||||
return addFrameworkFiles(tree, context, {
|
return addFrameworkFiles(tree, context, {
|
||||||
@ -110,3 +111,12 @@ function addOtherFiles(options: SchematicsOptions): Rule {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateAngularConfig(options: SchematicsOptions): Rule {
|
||||||
|
return (tree: Tree, context: SchematicContext): Tree => {
|
||||||
|
context.logger.debug('Updating "angular.json".');
|
||||||
|
const script = getScriptFromOptions(options);
|
||||||
|
|
||||||
|
return updateAngularJsonScripts(tree, script);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
@ -1,7 +1,22 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2022 Google Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
import {getSystemPath, normalize, strings} from '@angular-devkit/core';
|
import {getSystemPath, normalize, strings} from '@angular-devkit/core';
|
||||||
import {
|
import {
|
||||||
SchematicContext,
|
SchematicContext,
|
||||||
SchematicsException,
|
|
||||||
Tree,
|
Tree,
|
||||||
apply,
|
apply,
|
||||||
applyTemplates,
|
applyTemplates,
|
||||||
@ -121,17 +136,18 @@ export function addFrameworkFiles(
|
|||||||
return addFiles(tree, context, options);
|
return addFiles(tree, context, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getScriptFromOptions(options: SchematicsOptions): string {
|
export function getScriptFromOptions(options: SchematicsOptions): string[][] {
|
||||||
switch (options.testingFramework) {
|
switch (options.testingFramework) {
|
||||||
case TestingFramework.Jasmine:
|
case TestingFramework.Jasmine:
|
||||||
return 'jasmine --config=./e2e/support/jasmine.json';
|
return [[`jasmine`, '--config=./e2e/support/jasmine.json']];
|
||||||
case TestingFramework.Jest:
|
case TestingFramework.Jest:
|
||||||
return 'jest -c e2e/jest.config.js';
|
return [[`jest`, '-c', 'e2e/jest.config.js']];
|
||||||
case TestingFramework.Mocha:
|
case TestingFramework.Mocha:
|
||||||
return 'mocha --config=./e2e/.mocharc.js';
|
return [[`mocha`, '--config=./e2e/.mocharc.js']];
|
||||||
case TestingFramework.Node:
|
case TestingFramework.Node:
|
||||||
return 'tsc -p e2e/tsconfig.json && node --test e2e/out-tsc/**.js';
|
return [
|
||||||
default:
|
[`tsc`, '-p', 'e2e/tsconfig.json'],
|
||||||
throw new SchematicsException('Testing framework not supported.');
|
['node', '--test', 'e2e/'],
|
||||||
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,10 +14,14 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {SchematicsException, Tree} from '@angular-devkit/schematics';
|
import {Tree} from '@angular-devkit/schematics';
|
||||||
import {get} from 'https';
|
import {get} from 'https';
|
||||||
import {SchematicsOptions, TestingFramework} from './types.js';
|
import {SchematicsOptions, TestingFramework} from './types.js';
|
||||||
import {getJsonFileAsObject, getObjectAsJson} from './json.js';
|
import {
|
||||||
|
getAngularConfig,
|
||||||
|
getJsonFileAsObject,
|
||||||
|
getObjectAsJson,
|
||||||
|
} from './json.js';
|
||||||
export interface NodePackage {
|
export interface NodePackage {
|
||||||
name: string;
|
name: string;
|
||||||
version: string;
|
version: string;
|
||||||
@ -68,7 +72,7 @@ export function getPackageLatestNpmVersion(name: string): Promise<NodePackage> {
|
|||||||
function updateJsonValues(
|
function updateJsonValues(
|
||||||
json: Record<string, any>,
|
json: Record<string, any>,
|
||||||
target: string,
|
target: string,
|
||||||
updates: Array<{name: string; value: string}>,
|
updates: Array<{name: string; value: any}>,
|
||||||
overwrite = false
|
overwrite = false
|
||||||
) {
|
) {
|
||||||
updates.forEach(({name, value}) => {
|
updates.forEach(({name, value}) => {
|
||||||
@ -128,8 +132,6 @@ export function getDependenciesFromOptions(
|
|||||||
case TestingFramework.Node:
|
case TestingFramework.Node:
|
||||||
dependencies.push('@types/node');
|
dependencies.push('@types/node');
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
throw new SchematicsException(`Testing framework not supported.`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return dependencies;
|
return dependencies;
|
||||||
@ -156,3 +158,36 @@ export function addPackageJsonScripts(
|
|||||||
|
|
||||||
return tree;
|
return tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function updateAngularJsonScripts(
|
||||||
|
tree: Tree,
|
||||||
|
commands: string[][],
|
||||||
|
overwrite = true
|
||||||
|
): Tree {
|
||||||
|
const angularJson = getAngularConfig(tree);
|
||||||
|
|
||||||
|
const e2eScript = [
|
||||||
|
{
|
||||||
|
name: 'e2e',
|
||||||
|
value: {
|
||||||
|
builder: '@puppeteer/ng-schematics:puppeteer',
|
||||||
|
options: {
|
||||||
|
commands,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
Object.keys(angularJson['projects']).forEach(project => {
|
||||||
|
updateJsonValues(
|
||||||
|
angularJson['projects'][project],
|
||||||
|
'architect',
|
||||||
|
e2eScript,
|
||||||
|
overwrite
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
tree.overwrite('./angular.json', getObjectAsJson(angularJson));
|
||||||
|
|
||||||
|
return tree;
|
||||||
|
}
|
||||||
|
@ -22,6 +22,11 @@ function getProjectFile(file: string): string {
|
|||||||
return `/${WORKSPACE_OPTIONS.newProjectRoot}/${APPLICATION_OPTIONS.name}/${file}`;
|
return `/${WORKSPACE_OPTIONS.newProjectRoot}/${APPLICATION_OPTIONS.name}/${file}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getAngularJsonScripts(tree: UnitTestTree): Record<string, any> {
|
||||||
|
const angularJson = tree.readJson('angular.json') as any;
|
||||||
|
return angularJson['projects']?.[APPLICATION_OPTIONS.name]?.['architect'];
|
||||||
|
}
|
||||||
|
|
||||||
function getPackageJson(tree: UnitTestTree): {
|
function getPackageJson(tree: UnitTestTree): {
|
||||||
scripts: Record<string, string>;
|
scripts: Record<string, string>;
|
||||||
devDependencies: string[];
|
devDependencies: string[];
|
||||||
@ -87,11 +92,14 @@ describe('@puppeteer/ng-schematics: ng-add', () => {
|
|||||||
|
|
||||||
it('should create base files and update to "package.json"', async () => {
|
it('should create base files and update to "package.json"', async () => {
|
||||||
const tree = await buildTestingTree();
|
const tree = await buildTestingTree();
|
||||||
const {devDependencies} = getPackageJson(tree);
|
const {devDependencies, scripts} = getPackageJson(tree);
|
||||||
|
const {e2e} = getAngularJsonScripts(tree);
|
||||||
|
|
||||||
expect(tree.files).toContain(getProjectFile('e2e/tsconfig.json'));
|
expect(tree.files).toContain(getProjectFile('e2e/tsconfig.json'));
|
||||||
expect(tree.files).toContain(getProjectFile('e2e/tests/app.e2e.ts'));
|
expect(tree.files).toContain(getProjectFile('e2e/tests/app.e2e.ts'));
|
||||||
expect(devDependencies).toContain('puppeteer');
|
expect(devDependencies).toContain('puppeteer');
|
||||||
|
expect(scripts['e2e']).toBe('ng e2e');
|
||||||
|
expect(e2e.builder).toBe('@puppeteer/ng-schematics:puppeteer');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create Puppeteer config', async () => {
|
it('should create Puppeteer config', async () => {
|
||||||
@ -114,55 +122,65 @@ describe('@puppeteer/ng-schematics: ng-add', () => {
|
|||||||
const tree = await buildTestingTree({
|
const tree = await buildTestingTree({
|
||||||
testingFramework: 'jasmine',
|
testingFramework: 'jasmine',
|
||||||
});
|
});
|
||||||
const {scripts, devDependencies} = getPackageJson(tree);
|
const {devDependencies} = getPackageJson(tree);
|
||||||
|
const {e2e} = getAngularJsonScripts(tree);
|
||||||
|
|
||||||
expect(tree.files).toContain(getProjectFile('e2e/support/jasmine.json'));
|
expect(tree.files).toContain(getProjectFile('e2e/support/jasmine.json'));
|
||||||
expect(tree.files).toContain(getProjectFile('e2e/helpers/babel.js'));
|
expect(tree.files).toContain(getProjectFile('e2e/helpers/babel.js'));
|
||||||
expect(scripts['e2e']).toBe('jasmine --config=./e2e/support/jasmine.json');
|
|
||||||
expect(devDependencies).toContain('jasmine');
|
expect(devDependencies).toContain('jasmine');
|
||||||
expect(devDependencies).toContain('@babel/core');
|
expect(devDependencies).toContain('@babel/core');
|
||||||
expect(devDependencies).toContain('@babel/register');
|
expect(devDependencies).toContain('@babel/register');
|
||||||
expect(devDependencies).toContain('@babel/preset-typescript');
|
expect(devDependencies).toContain('@babel/preset-typescript');
|
||||||
|
expect(e2e.options.commands).toEqual([
|
||||||
|
[`jasmine`, '--config=./e2e/support/jasmine.json'],
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create Jest files and update "package.json"', async () => {
|
it('should create Jest files and update "package.json"', async () => {
|
||||||
const tree = await buildTestingTree({
|
const tree = await buildTestingTree({
|
||||||
testingFramework: 'jest',
|
testingFramework: 'jest',
|
||||||
});
|
});
|
||||||
const {scripts, devDependencies} = getPackageJson(tree);
|
const {devDependencies} = getPackageJson(tree);
|
||||||
|
const {e2e} = getAngularJsonScripts(tree);
|
||||||
|
|
||||||
expect(tree.files).toContain(getProjectFile('e2e/jest.config.js'));
|
expect(tree.files).toContain(getProjectFile('e2e/jest.config.js'));
|
||||||
expect(scripts['e2e']).toBe('jest -c e2e/jest.config.js');
|
|
||||||
expect(devDependencies).toContain('jest');
|
expect(devDependencies).toContain('jest');
|
||||||
expect(devDependencies).toContain('@types/jest');
|
expect(devDependencies).toContain('@types/jest');
|
||||||
expect(devDependencies).toContain('ts-jest');
|
expect(devDependencies).toContain('ts-jest');
|
||||||
|
expect(e2e.options.commands).toEqual([
|
||||||
|
[`jest`, '-c', 'e2e/jest.config.js'],
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create Jasmine files and update "package.json"', async () => {
|
it('should create Mocha files and update "package.json"', async () => {
|
||||||
const tree = await buildTestingTree({
|
const tree = await buildTestingTree({
|
||||||
testingFramework: 'mocha',
|
testingFramework: 'mocha',
|
||||||
});
|
});
|
||||||
const {scripts, devDependencies} = getPackageJson(tree);
|
const {devDependencies} = getPackageJson(tree);
|
||||||
|
const {e2e} = getAngularJsonScripts(tree);
|
||||||
|
|
||||||
expect(tree.files).toContain(getProjectFile('e2e/.mocharc.js'));
|
expect(tree.files).toContain(getProjectFile('e2e/.mocharc.js'));
|
||||||
expect(tree.files).toContain(getProjectFile('e2e/babel.js'));
|
expect(tree.files).toContain(getProjectFile('e2e/babel.js'));
|
||||||
expect(scripts['e2e']).toBe('mocha --config=./e2e/.mocharc.js');
|
|
||||||
expect(devDependencies).toContain('mocha');
|
expect(devDependencies).toContain('mocha');
|
||||||
expect(devDependencies).toContain('@types/mocha');
|
expect(devDependencies).toContain('@types/mocha');
|
||||||
expect(devDependencies).toContain('@babel/core');
|
expect(devDependencies).toContain('@babel/core');
|
||||||
expect(devDependencies).toContain('@babel/register');
|
expect(devDependencies).toContain('@babel/register');
|
||||||
expect(devDependencies).toContain('@babel/preset-typescript');
|
expect(devDependencies).toContain('@babel/preset-typescript');
|
||||||
|
expect(e2e.options.commands).toEqual([
|
||||||
|
[`mocha`, '--config=./e2e/.mocharc.js'],
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create Node files"', async () => {
|
it('should create Node files"', async () => {
|
||||||
const tree = await buildTestingTree({
|
const tree = await buildTestingTree({
|
||||||
testingFramework: 'node',
|
testingFramework: 'node',
|
||||||
});
|
});
|
||||||
const {scripts} = getPackageJson(tree);
|
const {e2e} = getAngularJsonScripts(tree);
|
||||||
|
|
||||||
expect(tree.files).toContain(getProjectFile('e2e/.gitignore'));
|
expect(tree.files).toContain(getProjectFile('e2e/.gitignore'));
|
||||||
expect(scripts['e2e']).toBe(
|
expect(e2e.options.commands).toEqual([
|
||||||
'tsc -p e2e/tsconfig.json && node --test e2e/out-tsc/**.js'
|
[`tsc`, '-p', 'e2e/tsconfig.json'],
|
||||||
);
|
['node', '--test', 'e2e/'],
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"extends": "../../tsconfig.base.json",
|
"extends": "../../tsconfig.base.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"baseUrl": "tsconfig",
|
"baseUrl": "tsconfig",
|
||||||
"lib": ["es2018", "dom"],
|
"lib": ["ES2018"],
|
||||||
"module": "CommonJS",
|
"module": "CommonJS",
|
||||||
"noEmitOnError": true,
|
"noEmitOnError": true,
|
||||||
"rootDir": "src/",
|
"rootDir": "src/",
|
||||||
|
Loading…
Reference in New Issue
Block a user