chore: tests for multi projects angular (#10675)
This commit is contained in:
parent
2f6870651e
commit
7ecfe150a1
@ -98,6 +98,12 @@ To run the creating of single test schematic:
|
||||
npm run sandbox:test
|
||||
```
|
||||
|
||||
To create a multi project workspace use the following command
|
||||
|
||||
```bash
|
||||
npm run sandbox -- --init --multi
|
||||
```
|
||||
|
||||
### Unit Testing
|
||||
|
||||
The schematics utilize `@angular-devkit/schematics/testing` for verifying correct file creation and `package.json` updates. To execute the test suit:
|
||||
|
@ -98,6 +98,12 @@ To run the creating of single test schematic:
|
||||
npm run sandbox:test
|
||||
```
|
||||
|
||||
To create a multi project workspace use the following command
|
||||
|
||||
```bash
|
||||
npm run sandbox -- --init --multi
|
||||
```
|
||||
|
||||
### Unit Testing
|
||||
|
||||
The schematics utilize `@angular-devkit/schematics/testing` for verifying correct file creation and `package.json` updates. To execute the test suit:
|
||||
|
@ -20,7 +20,8 @@ import {of} from 'rxjs';
|
||||
import {concatMap, map, scan} from 'rxjs/operators';
|
||||
|
||||
import {
|
||||
addBaseFiles,
|
||||
addCommonFiles as addCommonFilesHelper,
|
||||
addFilesSingle,
|
||||
addFrameworkFiles,
|
||||
getNgCommandName,
|
||||
} from '../utils/files.js';
|
||||
@ -34,15 +35,22 @@ import {
|
||||
type NodePackage,
|
||||
updateAngularJsonScripts,
|
||||
} from '../utils/packages.js';
|
||||
import {TestingFramework, type SchematicsOptions} from '../utils/types.js';
|
||||
import {
|
||||
TestingFramework,
|
||||
type SchematicsOptions,
|
||||
AngularProject,
|
||||
} from '../utils/types.js';
|
||||
|
||||
// You don't have to export the function as default. You can also have more than one rule
|
||||
// factory per file.
|
||||
export function ngAdd(options: SchematicsOptions): Rule {
|
||||
export function ngAdd(userArgs: Record<string, string>): Rule {
|
||||
const options = parseUserAddArgs(userArgs);
|
||||
|
||||
return (tree: Tree, context: SchematicContext) => {
|
||||
return chain([
|
||||
addDependencies(options),
|
||||
addPuppeteerFiles(options),
|
||||
addPuppeteerConfig(options),
|
||||
addCommonFiles(options),
|
||||
addOtherFiles(options),
|
||||
updateScripts(options),
|
||||
updateAngularConfig(options),
|
||||
@ -50,6 +58,32 @@ export function ngAdd(options: SchematicsOptions): Rule {
|
||||
};
|
||||
}
|
||||
|
||||
function parseUserAddArgs(userArgs: Record<string, string>): SchematicsOptions {
|
||||
const options: Partial<SchematicsOptions> = {
|
||||
...userArgs,
|
||||
};
|
||||
if ('p' in userArgs) {
|
||||
options['port'] = Number(userArgs['p']);
|
||||
}
|
||||
if ('t' in userArgs) {
|
||||
options['testingFramework'] = userArgs['t'] as TestingFramework;
|
||||
}
|
||||
if ('c' in userArgs) {
|
||||
options['exportConfig'] =
|
||||
typeof userArgs['c'] === 'string'
|
||||
? userArgs['c'] === 'true'
|
||||
: userArgs['c'];
|
||||
}
|
||||
if ('d' in userArgs) {
|
||||
options['isDefaultTester'] =
|
||||
typeof userArgs['d'] === 'string'
|
||||
? userArgs['d'] === 'true'
|
||||
: userArgs['d'];
|
||||
}
|
||||
|
||||
return options as SchematicsOptions;
|
||||
}
|
||||
|
||||
function addDependencies(options: SchematicsOptions): Rule {
|
||||
return (tree: Tree, context: SchematicContext) => {
|
||||
context.logger.debug('Adding dependencies to "package.json"');
|
||||
@ -94,13 +128,28 @@ function updateScripts(options: SchematicsOptions): Rule {
|
||||
};
|
||||
}
|
||||
|
||||
function addPuppeteerFiles(options: SchematicsOptions): Rule {
|
||||
function addPuppeteerConfig(options: SchematicsOptions): Rule {
|
||||
return (tree: Tree, context: SchematicContext) => {
|
||||
context.logger.debug('Adding Puppeteer config file.');
|
||||
|
||||
if (options.exportConfig) {
|
||||
return addFilesSingle(tree, context, '', {root: ''} as AngularProject, {
|
||||
options: options,
|
||||
applyPath: './files/base',
|
||||
relativeToWorkspacePath: `/`,
|
||||
});
|
||||
}
|
||||
|
||||
return tree;
|
||||
};
|
||||
}
|
||||
|
||||
function addCommonFiles(options: SchematicsOptions): Rule {
|
||||
return (tree: Tree, context: SchematicContext) => {
|
||||
context.logger.debug('Adding Puppeteer base files.');
|
||||
const {projects} = getAngularConfig(tree);
|
||||
|
||||
return addBaseFiles(tree, context, {
|
||||
projects,
|
||||
return addCommonFilesHelper(tree, context, projects, {
|
||||
options: {
|
||||
...options,
|
||||
ext:
|
||||
@ -115,8 +164,7 @@ function addOtherFiles(options: SchematicsOptions): Rule {
|
||||
context.logger.debug('Adding Puppeteer additional files.');
|
||||
const {projects} = getAngularConfig(tree);
|
||||
|
||||
return addFrameworkFiles(tree, context, {
|
||||
projects,
|
||||
return addFrameworkFiles(tree, context, projects, {
|
||||
options,
|
||||
});
|
||||
};
|
||||
|
@ -22,7 +22,7 @@ import {
|
||||
Tree,
|
||||
} from '@angular-devkit/schematics';
|
||||
|
||||
import {addBaseFiles} from '../utils/files.js';
|
||||
import {addCommonFiles} from '../utils/files.js';
|
||||
import {getAngularConfig} from '../utils/json.js';
|
||||
import {
|
||||
TestingFramework,
|
||||
@ -33,12 +33,28 @@ import {
|
||||
|
||||
// You don't have to export the function as default. You can also have more than one rule
|
||||
// factory per file.
|
||||
export function test(options: SchematicsSpec): Rule {
|
||||
export function test(userArgs: Record<string, string>): Rule {
|
||||
const options = parseUserTestArgs(userArgs);
|
||||
|
||||
return (tree: Tree, context: SchematicContext) => {
|
||||
return chain([addSpecFile(options)])(tree, context);
|
||||
};
|
||||
}
|
||||
|
||||
function parseUserTestArgs(userArgs: Record<string, string>): SchematicsSpec {
|
||||
const options: Partial<SchematicsSpec> = {
|
||||
...userArgs,
|
||||
};
|
||||
if ('p' in userArgs) {
|
||||
options['project'] = userArgs['p'];
|
||||
}
|
||||
if ('n' in userArgs) {
|
||||
options['name'] = userArgs['n'];
|
||||
}
|
||||
|
||||
return options as SchematicsSpec;
|
||||
}
|
||||
|
||||
function findTestingOption<Property extends keyof SchematicsOptions>(
|
||||
[name, project]: [string, AngularProject | undefined],
|
||||
property: Property
|
||||
@ -76,7 +92,7 @@ function addSpecFile(options: SchematicsSpec): Rule {
|
||||
});
|
||||
if (!foundProject) {
|
||||
throw new SchematicsException(
|
||||
`Project not found! Please use -p to specify in which project to run.`
|
||||
`Project not found! Please run "ng generate @puppeteer/ng-schematics:test <Test> <Project>"`
|
||||
);
|
||||
}
|
||||
|
||||
@ -88,16 +104,20 @@ function addSpecFile(options: SchematicsSpec): Rule {
|
||||
|
||||
context.logger.debug('Creating Spec file.');
|
||||
|
||||
return addBaseFiles(tree, context, {
|
||||
projects: {[foundProject[0]]: foundProject[1]},
|
||||
options: {
|
||||
name: options.name,
|
||||
testingFramework,
|
||||
// Node test runner does not support glob patterns
|
||||
// It looks for files `*.test.js`
|
||||
ext: testingFramework === TestingFramework.Node ? 'test' : 'e2e',
|
||||
port,
|
||||
},
|
||||
});
|
||||
return addCommonFiles(
|
||||
tree,
|
||||
context,
|
||||
{[foundProject[0]]: foundProject[1]} as Record<string, AngularProject>,
|
||||
{
|
||||
options: {
|
||||
name: options.name,
|
||||
testingFramework,
|
||||
// Node test runner does not support glob patterns
|
||||
// It looks for files `*.test.js`
|
||||
ext: testingFramework === TestingFramework.Node ? 'test' : 'e2e',
|
||||
port,
|
||||
},
|
||||
}
|
||||
);
|
||||
};
|
||||
}
|
||||
|
@ -15,6 +15,10 @@
|
||||
},
|
||||
"project": {
|
||||
"type": "string",
|
||||
"$default": {
|
||||
"$source": "argv",
|
||||
"index": 1
|
||||
},
|
||||
"alias": "p"
|
||||
}
|
||||
},
|
||||
|
@ -23,7 +23,6 @@ import {
|
||||
apply,
|
||||
applyTemplates,
|
||||
chain,
|
||||
filter,
|
||||
mergeWith,
|
||||
move,
|
||||
url,
|
||||
@ -32,7 +31,6 @@ import {
|
||||
import {AngularProject, SchematicsOptions, TestingFramework} from './types.js';
|
||||
|
||||
export interface FilesOptions {
|
||||
projects: Record<string, any>;
|
||||
options: {
|
||||
testingFramework: TestingFramework;
|
||||
port: number;
|
||||
@ -43,61 +41,61 @@ export interface FilesOptions {
|
||||
applyPath: string;
|
||||
relativeToWorkspacePath: string;
|
||||
movePath?: string;
|
||||
filterPredicate?: (path: string) => boolean;
|
||||
}
|
||||
|
||||
const PUPPETEER_CONFIG_TEMPLATE = '.puppeteerrc.cjs.template';
|
||||
|
||||
export function addFiles(
|
||||
export function addFilesToProjects(
|
||||
tree: Tree,
|
||||
context: SchematicContext,
|
||||
{
|
||||
projects,
|
||||
options,
|
||||
applyPath,
|
||||
movePath,
|
||||
relativeToWorkspacePath,
|
||||
filterPredicate,
|
||||
}: FilesOptions
|
||||
projects: Record<string, AngularProject>,
|
||||
options: FilesOptions
|
||||
): any {
|
||||
return chain(
|
||||
Object.keys(projects).map(name => {
|
||||
const project = projects[name] as AngularProject;
|
||||
const projectPath = resolve(getSystemPath(normalize(project.root)));
|
||||
const workspacePath = resolve(getSystemPath(normalize('')));
|
||||
|
||||
const relativeToWorkspace = relative(
|
||||
`${projectPath}${relativeToWorkspacePath}`,
|
||||
workspacePath
|
||||
);
|
||||
|
||||
const baseUrl = getProjectBaseUrl(project, options.port);
|
||||
const tsConfigPath = getTsConfigPath(project);
|
||||
|
||||
return mergeWith(
|
||||
apply(url(applyPath), [
|
||||
filter(
|
||||
filterPredicate ??
|
||||
(() => {
|
||||
return true;
|
||||
})
|
||||
),
|
||||
move(movePath ? `${project.root}${movePath}` : project.root),
|
||||
applyTemplates({
|
||||
...options,
|
||||
...strings,
|
||||
root: project.root ? `${project.root}/` : project.root,
|
||||
baseUrl,
|
||||
tsConfigPath,
|
||||
project: name,
|
||||
relativeToWorkspace,
|
||||
}),
|
||||
])
|
||||
return addFilesSingle(
|
||||
tree,
|
||||
context,
|
||||
name,
|
||||
projects[name] as AngularProject,
|
||||
options
|
||||
);
|
||||
})
|
||||
)(tree, context);
|
||||
}
|
||||
|
||||
export function addFilesSingle(
|
||||
_tree: Tree,
|
||||
_context: SchematicContext,
|
||||
name: string,
|
||||
project: AngularProject,
|
||||
{options, applyPath, movePath, relativeToWorkspacePath}: FilesOptions
|
||||
): any {
|
||||
const projectPath = resolve(getSystemPath(normalize(project.root)));
|
||||
const workspacePath = resolve(getSystemPath(normalize('')));
|
||||
|
||||
const relativeToWorkspace = relative(
|
||||
`${projectPath}${relativeToWorkspacePath}`,
|
||||
workspacePath
|
||||
);
|
||||
|
||||
const baseUrl = getProjectBaseUrl(project, options.port);
|
||||
const tsConfigPath = getTsConfigPath(project);
|
||||
|
||||
return mergeWith(
|
||||
apply(url(applyPath), [
|
||||
move(movePath ? `${project.root}${movePath}` : project.root),
|
||||
applyTemplates({
|
||||
...options,
|
||||
...strings,
|
||||
root: project.root ? `${project.root}/` : project.root,
|
||||
baseUrl,
|
||||
tsConfigPath,
|
||||
project: name,
|
||||
relativeToWorkspace,
|
||||
}),
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
function getProjectBaseUrl(project: any, port: number): string {
|
||||
let options = {protocol: 'http', port, host: 'localhost'};
|
||||
|
||||
@ -118,29 +116,25 @@ function getTsConfigPath(project: AngularProject): string {
|
||||
return `../tsconfig.app.json`;
|
||||
}
|
||||
|
||||
export function addBaseFiles(
|
||||
export function addCommonFiles(
|
||||
tree: Tree,
|
||||
context: SchematicContext,
|
||||
projects: Record<string, AngularProject>,
|
||||
filesOptions: Omit<FilesOptions, 'applyPath' | 'relativeToWorkspacePath'>
|
||||
): any {
|
||||
const options: FilesOptions = {
|
||||
...filesOptions,
|
||||
applyPath: './files/base',
|
||||
applyPath: './files/common',
|
||||
relativeToWorkspacePath: `/`,
|
||||
filterPredicate: path => {
|
||||
return path.includes(PUPPETEER_CONFIG_TEMPLATE) &&
|
||||
!filesOptions.options.exportConfig
|
||||
? false
|
||||
: true;
|
||||
},
|
||||
};
|
||||
|
||||
return addFiles(tree, context, options);
|
||||
return addFilesToProjects(tree, context, projects, options);
|
||||
}
|
||||
|
||||
export function addFrameworkFiles(
|
||||
tree: Tree,
|
||||
context: SchematicContext,
|
||||
projects: Record<string, AngularProject>,
|
||||
filesOptions: Omit<FilesOptions, 'applyPath' | 'relativeToWorkspacePath'>
|
||||
): any {
|
||||
const testingFramework = filesOptions.options.testingFramework;
|
||||
@ -150,7 +144,7 @@ export function addFrameworkFiles(
|
||||
relativeToWorkspacePath: `/`,
|
||||
};
|
||||
|
||||
return addFiles(tree, context, options);
|
||||
return addFilesToProjects(tree, context, projects, options);
|
||||
}
|
||||
|
||||
export function getScriptFromOptions(
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
import {SchematicsException, Tree} from '@angular-devkit/schematics';
|
||||
|
||||
import {AngularJson} from './types.js';
|
||||
import type {AngularJson} from './types.js';
|
||||
|
||||
export function getJsonFileAsObject(
|
||||
tree: Tree,
|
||||
|
@ -3,6 +3,7 @@ import expect from 'expect';
|
||||
import {
|
||||
buildTestingTree,
|
||||
getAngularJsonScripts,
|
||||
getMultiProjectFile,
|
||||
getPackageJson,
|
||||
setupHttpHooks,
|
||||
} from './utils.js';
|
||||
@ -10,132 +11,259 @@ import {
|
||||
describe('@puppeteer/ng-schematics: ng-add', () => {
|
||||
setupHttpHooks();
|
||||
|
||||
it('should create base files and update to "package.json"', async () => {
|
||||
const tree = await buildTestingTree('ng-add');
|
||||
const {devDependencies, scripts} = getPackageJson(tree);
|
||||
const {builder, configurations} = getAngularJsonScripts(tree);
|
||||
describe('Single Project', () => {
|
||||
it('should create base files and update to "package.json"', async () => {
|
||||
const tree = await buildTestingTree('ng-add');
|
||||
const {devDependencies, scripts} = getPackageJson(tree);
|
||||
const {builder, configurations} = getAngularJsonScripts(tree);
|
||||
|
||||
expect(tree.files).toContain('/e2e/tsconfig.json');
|
||||
expect(tree.files).toContain('/e2e/tests/app.e2e.ts');
|
||||
expect(tree.files).toContain('/e2e/tests/utils.ts');
|
||||
expect(devDependencies).toContain('puppeteer');
|
||||
expect(scripts['e2e']).toBe('ng e2e');
|
||||
expect(builder).toBe('@puppeteer/ng-schematics:puppeteer');
|
||||
expect(configurations).toEqual({
|
||||
production: {
|
||||
devServerTarget: 'sandbox:serve:production',
|
||||
},
|
||||
expect(tree.files).toContain('/e2e/tsconfig.json');
|
||||
expect(tree.files).toContain('/e2e/tests/app.e2e.ts');
|
||||
expect(tree.files).toContain('/e2e/tests/utils.ts');
|
||||
expect(devDependencies).toContain('puppeteer');
|
||||
expect(scripts['e2e']).toBe('ng e2e');
|
||||
expect(builder).toBe('@puppeteer/ng-schematics:puppeteer');
|
||||
expect(configurations).toEqual({
|
||||
production: {
|
||||
devServerTarget: 'sandbox:serve:production',
|
||||
},
|
||||
});
|
||||
});
|
||||
it('should update create proper "ng" command for non default tester', async () => {
|
||||
const tree = await buildTestingTree('ng-add', 'single', {
|
||||
isDefaultTester: false,
|
||||
});
|
||||
const {scripts} = getPackageJson(tree);
|
||||
const {builder} = getAngularJsonScripts(tree, false);
|
||||
|
||||
expect(scripts['puppeteer']).toBe('ng run sandbox:puppeteer');
|
||||
expect(builder).toBe('@puppeteer/ng-schematics:puppeteer');
|
||||
});
|
||||
it('should create Puppeteer config', async () => {
|
||||
const {files} = await buildTestingTree('ng-add', 'single', {
|
||||
exportConfig: true,
|
||||
});
|
||||
|
||||
expect(files).toContain('/.puppeteerrc.cjs');
|
||||
});
|
||||
it('should not create Puppeteer config', async () => {
|
||||
const {files} = await buildTestingTree('ng-add', 'single', {
|
||||
exportConfig: false,
|
||||
});
|
||||
|
||||
expect(files).not.toContain('/.puppeteerrc.cjs');
|
||||
});
|
||||
it('should create Jasmine files and update "package.json"', async () => {
|
||||
const tree = await buildTestingTree('ng-add', 'single', {
|
||||
testingFramework: 'jasmine',
|
||||
});
|
||||
const {devDependencies} = getPackageJson(tree);
|
||||
const {options} = getAngularJsonScripts(tree);
|
||||
|
||||
expect(tree.files).toContain('/e2e/support/jasmine.json');
|
||||
expect(tree.files).toContain('/e2e/helpers/babel.js');
|
||||
expect(devDependencies).toContain('jasmine');
|
||||
expect(devDependencies).toContain('@babel/core');
|
||||
expect(devDependencies).toContain('@babel/register');
|
||||
expect(devDependencies).toContain('@babel/preset-typescript');
|
||||
expect(options['commands']).toEqual([
|
||||
[`./node_modules/.bin/jasmine`, '--config=./e2e/support/jasmine.json'],
|
||||
]);
|
||||
});
|
||||
it('should create Jest files and update "package.json"', async () => {
|
||||
const tree = await buildTestingTree('ng-add', 'single', {
|
||||
testingFramework: 'jest',
|
||||
});
|
||||
const {devDependencies} = getPackageJson(tree);
|
||||
const {options} = getAngularJsonScripts(tree);
|
||||
|
||||
expect(tree.files).toContain('/e2e/jest.config.js');
|
||||
expect(devDependencies).toContain('jest');
|
||||
expect(devDependencies).toContain('@types/jest');
|
||||
expect(devDependencies).toContain('ts-jest');
|
||||
expect(options['commands']).toEqual([
|
||||
[`./node_modules/.bin/jest`, '-c', 'e2e/jest.config.js'],
|
||||
]);
|
||||
});
|
||||
it('should create Mocha files and update "package.json"', async () => {
|
||||
const tree = await buildTestingTree('ng-add', 'single', {
|
||||
testingFramework: 'mocha',
|
||||
});
|
||||
const {devDependencies} = getPackageJson(tree);
|
||||
const {options} = getAngularJsonScripts(tree);
|
||||
|
||||
expect(tree.files).toContain('/e2e/.mocharc.js');
|
||||
expect(tree.files).toContain('/e2e/babel.js');
|
||||
expect(devDependencies).toContain('mocha');
|
||||
expect(devDependencies).toContain('@types/mocha');
|
||||
expect(devDependencies).toContain('@babel/core');
|
||||
expect(devDependencies).toContain('@babel/register');
|
||||
expect(devDependencies).toContain('@babel/preset-typescript');
|
||||
expect(options['commands']).toEqual([
|
||||
[`./node_modules/.bin/mocha`, '--config=./e2e/.mocharc.js'],
|
||||
]);
|
||||
});
|
||||
it('should create Node files', async () => {
|
||||
const tree = await buildTestingTree('ng-add', 'single', {
|
||||
testingFramework: 'node',
|
||||
});
|
||||
const {options} = getAngularJsonScripts(tree);
|
||||
|
||||
expect(tree.files).toContain('/e2e/.gitignore');
|
||||
expect(tree.files).not.toContain('/e2e/tests/app.e2e.ts');
|
||||
expect(tree.files).toContain('/e2e/tests/app.test.ts');
|
||||
expect(options['commands']).toEqual([
|
||||
[`./node_modules/.bin/tsc`, '-p', 'e2e/tsconfig.json'],
|
||||
['node', '--test', '--test-reporter', 'spec', 'e2e/build/'],
|
||||
]);
|
||||
});
|
||||
it('should not create port option', async () => {
|
||||
const tree = await buildTestingTree('ng-add');
|
||||
|
||||
const {options} = getAngularJsonScripts(tree);
|
||||
expect(options['port']).toBeUndefined();
|
||||
});
|
||||
it('should create port option when specified', async () => {
|
||||
const port = 8080;
|
||||
const tree = await buildTestingTree('ng-add', 'single', {
|
||||
port,
|
||||
});
|
||||
|
||||
const {options} = getAngularJsonScripts(tree);
|
||||
expect(options['port']).toBe(port);
|
||||
});
|
||||
});
|
||||
|
||||
it('should update create proper "ng" command for non default tester', async () => {
|
||||
const tree = await buildTestingTree('ng-add', {
|
||||
isDefaultTester: false,
|
||||
describe('Multi projects', () => {
|
||||
it('should create base files and update to "package.json"', async () => {
|
||||
const tree = await buildTestingTree('ng-add', 'multi');
|
||||
const {devDependencies, scripts} = getPackageJson(tree);
|
||||
const {builder, configurations} = getAngularJsonScripts(tree);
|
||||
|
||||
expect(tree.files).toContain(getMultiProjectFile('e2e/tsconfig.json'));
|
||||
expect(tree.files).toContain(getMultiProjectFile('e2e/tests/app.e2e.ts'));
|
||||
expect(tree.files).toContain(getMultiProjectFile('e2e/tests/utils.ts'));
|
||||
expect(devDependencies).toContain('puppeteer');
|
||||
expect(scripts['e2e']).toBe('ng e2e');
|
||||
expect(builder).toBe('@puppeteer/ng-schematics:puppeteer');
|
||||
expect(configurations).toEqual({
|
||||
production: {
|
||||
devServerTarget: 'sandbox:serve:production',
|
||||
},
|
||||
});
|
||||
});
|
||||
const {scripts} = getPackageJson(tree);
|
||||
const {builder} = getAngularJsonScripts(tree, false);
|
||||
it('should update create proper "ng" command for non default tester', async () => {
|
||||
const tree = await buildTestingTree('ng-add', 'multi', {
|
||||
isDefaultTester: false,
|
||||
});
|
||||
const {scripts} = getPackageJson(tree);
|
||||
const {builder} = getAngularJsonScripts(tree, false);
|
||||
|
||||
expect(scripts['puppeteer']).toBe('ng run sandbox:puppeteer');
|
||||
expect(builder).toBe('@puppeteer/ng-schematics:puppeteer');
|
||||
});
|
||||
|
||||
it('should create Puppeteer config', async () => {
|
||||
const {files} = await buildTestingTree('ng-add', {
|
||||
exportConfig: true,
|
||||
expect(scripts['puppeteer']).toBe('ng run sandbox:puppeteer');
|
||||
expect(builder).toBe('@puppeteer/ng-schematics:puppeteer');
|
||||
});
|
||||
it('should create Puppeteer config', async () => {
|
||||
const {files} = await buildTestingTree('ng-add', 'multi', {
|
||||
exportConfig: true,
|
||||
});
|
||||
|
||||
expect(files).toContain('/.puppeteerrc.cjs');
|
||||
});
|
||||
|
||||
it('should not create Puppeteer config', async () => {
|
||||
const {files} = await buildTestingTree('ng-add', {
|
||||
exportConfig: false,
|
||||
expect(files).toContain('/.puppeteerrc.cjs');
|
||||
});
|
||||
it('should not create Puppeteer config', async () => {
|
||||
const {files} = await buildTestingTree('ng-add', 'multi', {
|
||||
exportConfig: false,
|
||||
});
|
||||
|
||||
expect(files).not.toContain('/.puppeteerrc.cjs');
|
||||
});
|
||||
|
||||
it('should create Jasmine files and update "package.json"', async () => {
|
||||
const tree = await buildTestingTree('ng-add', {
|
||||
testingFramework: 'jasmine',
|
||||
expect(files).not.toContain(getMultiProjectFile('.puppeteerrc.cjs'));
|
||||
expect(files).not.toContain('/.puppeteerrc.cjs');
|
||||
});
|
||||
const {devDependencies} = getPackageJson(tree);
|
||||
const {options} = getAngularJsonScripts(tree);
|
||||
it('should create Jasmine files and update "package.json"', async () => {
|
||||
const tree = await buildTestingTree('ng-add', 'multi', {
|
||||
testingFramework: 'jasmine',
|
||||
});
|
||||
const {devDependencies} = getPackageJson(tree);
|
||||
const {options} = getAngularJsonScripts(tree);
|
||||
|
||||
expect(tree.files).toContain('/e2e/support/jasmine.json');
|
||||
expect(tree.files).toContain('/e2e/helpers/babel.js');
|
||||
expect(devDependencies).toContain('jasmine');
|
||||
expect(devDependencies).toContain('@babel/core');
|
||||
expect(devDependencies).toContain('@babel/register');
|
||||
expect(devDependencies).toContain('@babel/preset-typescript');
|
||||
expect(options['commands']).toEqual([
|
||||
[`./node_modules/.bin/jasmine`, '--config=./e2e/support/jasmine.json'],
|
||||
]);
|
||||
});
|
||||
|
||||
it('should create Jest files and update "package.json"', async () => {
|
||||
const tree = await buildTestingTree('ng-add', {
|
||||
testingFramework: 'jest',
|
||||
expect(tree.files).toContain(
|
||||
getMultiProjectFile('e2e/support/jasmine.json')
|
||||
);
|
||||
expect(tree.files).toContain(getMultiProjectFile('e2e/helpers/babel.js'));
|
||||
expect(devDependencies).toContain('jasmine');
|
||||
expect(devDependencies).toContain('@babel/core');
|
||||
expect(devDependencies).toContain('@babel/register');
|
||||
expect(devDependencies).toContain('@babel/preset-typescript');
|
||||
expect(options['commands']).toEqual([
|
||||
[
|
||||
`../../node_modules/.bin/jasmine`,
|
||||
'--config=./e2e/support/jasmine.json',
|
||||
],
|
||||
]);
|
||||
});
|
||||
const {devDependencies} = getPackageJson(tree);
|
||||
const {options} = getAngularJsonScripts(tree);
|
||||
it('should create Jest files and update "package.json"', async () => {
|
||||
const tree = await buildTestingTree('ng-add', 'multi', {
|
||||
testingFramework: 'jest',
|
||||
});
|
||||
const {devDependencies} = getPackageJson(tree);
|
||||
const {options} = getAngularJsonScripts(tree);
|
||||
|
||||
expect(tree.files).toContain('/e2e/jest.config.js');
|
||||
expect(devDependencies).toContain('jest');
|
||||
expect(devDependencies).toContain('@types/jest');
|
||||
expect(devDependencies).toContain('ts-jest');
|
||||
expect(options['commands']).toEqual([
|
||||
[`./node_modules/.bin/jest`, '-c', 'e2e/jest.config.js'],
|
||||
]);
|
||||
});
|
||||
|
||||
it('should create Mocha files and update "package.json"', async () => {
|
||||
const tree = await buildTestingTree('ng-add', {
|
||||
testingFramework: 'mocha',
|
||||
expect(tree.files).toContain(getMultiProjectFile('e2e/jest.config.js'));
|
||||
expect(devDependencies).toContain('jest');
|
||||
expect(devDependencies).toContain('@types/jest');
|
||||
expect(devDependencies).toContain('ts-jest');
|
||||
expect(options['commands']).toEqual([
|
||||
[`../../node_modules/.bin/jest`, '-c', 'e2e/jest.config.js'],
|
||||
]);
|
||||
});
|
||||
const {devDependencies} = getPackageJson(tree);
|
||||
const {options} = getAngularJsonScripts(tree);
|
||||
it('should create Mocha files and update "package.json"', async () => {
|
||||
const tree = await buildTestingTree('ng-add', 'multi', {
|
||||
testingFramework: 'mocha',
|
||||
});
|
||||
const {devDependencies} = getPackageJson(tree);
|
||||
const {options} = getAngularJsonScripts(tree);
|
||||
|
||||
expect(tree.files).toContain('/e2e/.mocharc.js');
|
||||
expect(tree.files).toContain('/e2e/babel.js');
|
||||
expect(devDependencies).toContain('mocha');
|
||||
expect(devDependencies).toContain('@types/mocha');
|
||||
expect(devDependencies).toContain('@babel/core');
|
||||
expect(devDependencies).toContain('@babel/register');
|
||||
expect(devDependencies).toContain('@babel/preset-typescript');
|
||||
expect(options['commands']).toEqual([
|
||||
[`./node_modules/.bin/mocha`, '--config=./e2e/.mocharc.js'],
|
||||
]);
|
||||
});
|
||||
|
||||
it('should create Node files', async () => {
|
||||
const tree = await buildTestingTree('ng-add', {
|
||||
testingFramework: 'node',
|
||||
expect(tree.files).toContain(getMultiProjectFile('e2e/.mocharc.js'));
|
||||
expect(tree.files).toContain(getMultiProjectFile('e2e/babel.js'));
|
||||
expect(devDependencies).toContain('mocha');
|
||||
expect(devDependencies).toContain('@types/mocha');
|
||||
expect(devDependencies).toContain('@babel/core');
|
||||
expect(devDependencies).toContain('@babel/register');
|
||||
expect(devDependencies).toContain('@babel/preset-typescript');
|
||||
expect(options['commands']).toEqual([
|
||||
[`../../node_modules/.bin/mocha`, '--config=./e2e/.mocharc.js'],
|
||||
]);
|
||||
});
|
||||
const {options} = getAngularJsonScripts(tree);
|
||||
it('should create Node files', async () => {
|
||||
const tree = await buildTestingTree('ng-add', 'multi', {
|
||||
testingFramework: 'node',
|
||||
});
|
||||
const {options} = getAngularJsonScripts(tree);
|
||||
|
||||
expect(tree.files).toContain('/e2e/.gitignore');
|
||||
expect(tree.files).not.toContain('/e2e/tests/app.e2e.ts');
|
||||
expect(tree.files).toContain('/e2e/tests/app.test.ts');
|
||||
expect(options['commands']).toEqual([
|
||||
[`./node_modules/.bin/tsc`, '-p', 'e2e/tsconfig.json'],
|
||||
['node', '--test', '--test-reporter', 'spec', 'e2e/build/'],
|
||||
]);
|
||||
});
|
||||
|
||||
it('should not create port option', async () => {
|
||||
const tree = await buildTestingTree('ng-add');
|
||||
|
||||
const {options} = getAngularJsonScripts(tree);
|
||||
expect(options['port']).toBeUndefined();
|
||||
});
|
||||
it('should create port option when specified', async () => {
|
||||
const port = 8080;
|
||||
const tree = await buildTestingTree('ng-add', {
|
||||
port,
|
||||
expect(tree.files).toContain(getMultiProjectFile('e2e/.gitignore'));
|
||||
expect(tree.files).not.toContain(
|
||||
getMultiProjectFile('e2e/tests/app.e2e.ts')
|
||||
);
|
||||
expect(tree.files).toContain(
|
||||
getMultiProjectFile('e2e/tests/app.test.ts')
|
||||
);
|
||||
expect(options['commands']).toEqual([
|
||||
[`../../node_modules/.bin/tsc`, '-p', 'e2e/tsconfig.json'],
|
||||
['node', '--test', '--test-reporter', 'spec', 'e2e/build/'],
|
||||
]);
|
||||
});
|
||||
it('should not create port option', async () => {
|
||||
const tree = await buildTestingTree('ng-add');
|
||||
|
||||
const {options} = getAngularJsonScripts(tree);
|
||||
expect(options['port']).toBe(port);
|
||||
const {options} = getAngularJsonScripts(tree);
|
||||
expect(options['port']).toBeUndefined();
|
||||
});
|
||||
it('should create port option when specified', async () => {
|
||||
const port = 8080;
|
||||
const tree = await buildTestingTree('ng-add', 'multi', {
|
||||
port,
|
||||
});
|
||||
|
||||
const {options} = getAngularJsonScripts(tree);
|
||||
expect(options['port']).toBe(port);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,24 +1,57 @@
|
||||
import expect from 'expect';
|
||||
|
||||
import {buildTestingTree, setupHttpHooks} from './utils.js';
|
||||
import {
|
||||
buildTestingTree,
|
||||
getMultiProjectFile,
|
||||
setupHttpHooks,
|
||||
} from './utils.js';
|
||||
|
||||
describe('@puppeteer/ng-schematics: test', () => {
|
||||
setupHttpHooks();
|
||||
|
||||
it('should create default file', async () => {
|
||||
const tree = await buildTestingTree('test', {
|
||||
name: 'myTest',
|
||||
describe('Single Project', () => {
|
||||
it('should create default file', async () => {
|
||||
const tree = await buildTestingTree('test', 'single', {
|
||||
name: 'myTest',
|
||||
});
|
||||
expect(tree.files).toContain('/e2e/tests/my-test.e2e.ts');
|
||||
expect(tree.files).not.toContain('/e2e/tests/my-test.test.ts');
|
||||
});
|
||||
|
||||
it('should create Node file', async () => {
|
||||
const tree = await buildTestingTree('test', 'single', {
|
||||
name: 'myTest',
|
||||
testingFramework: 'node',
|
||||
});
|
||||
expect(tree.files).not.toContain('/e2e/tests/my-test.e2e.ts');
|
||||
expect(tree.files).toContain('/e2e/tests/my-test.test.ts');
|
||||
});
|
||||
expect(tree.files).toContain('/e2e/tests/my-test.e2e.ts');
|
||||
expect(tree.files).not.toContain('/e2e/tests/my-test.test.ts');
|
||||
});
|
||||
|
||||
it('should create Node file', async () => {
|
||||
const tree = await buildTestingTree('test', {
|
||||
name: 'myTest',
|
||||
testingFramework: 'node',
|
||||
describe('Multi projects', () => {
|
||||
it('should create default file', async () => {
|
||||
const tree = await buildTestingTree('test', 'multi', {
|
||||
name: 'myTest',
|
||||
});
|
||||
expect(tree.files).toContain(
|
||||
getMultiProjectFile('e2e/tests/my-test.e2e.ts')
|
||||
);
|
||||
expect(tree.files).not.toContain(
|
||||
getMultiProjectFile('e2e/tests/my-test.test.ts')
|
||||
);
|
||||
});
|
||||
|
||||
it('should create Node file', async () => {
|
||||
const tree = await buildTestingTree('test', 'multi', {
|
||||
name: 'myTest',
|
||||
testingFramework: 'node',
|
||||
});
|
||||
expect(tree.files).not.toContain(
|
||||
getMultiProjectFile('e2e/tests/my-test.e2e.ts')
|
||||
);
|
||||
expect(tree.files).toContain(
|
||||
getMultiProjectFile('e2e/tests/my-test.test.ts')
|
||||
);
|
||||
});
|
||||
expect(tree.files).not.toContain('/e2e/tests/my-test.e2e.ts');
|
||||
expect(tree.files).toContain('/e2e/tests/my-test.test.ts');
|
||||
});
|
||||
});
|
||||
|
@ -8,7 +8,17 @@ import {
|
||||
} from '@angular-devkit/schematics/testing';
|
||||
import sinon from 'sinon';
|
||||
|
||||
const APPLICATION_OPTIONS = {
|
||||
const WORKSPACE_OPTIONS = {
|
||||
name: 'workspace',
|
||||
newProjectRoot: 'projects',
|
||||
version: '14.0.0',
|
||||
};
|
||||
|
||||
const MULTI_APPLICATION_OPTIONS = {
|
||||
name: 'sandbox',
|
||||
};
|
||||
|
||||
const SINGLE_APPLICATION_OPTIONS = {
|
||||
name: 'sandbox',
|
||||
directory: '.',
|
||||
createApplication: true,
|
||||
@ -41,9 +51,9 @@ export function getAngularJsonScripts(
|
||||
} {
|
||||
const angularJson = tree.readJson('angular.json') as any;
|
||||
const e2eScript = isDefault ? 'e2e' : 'puppeteer';
|
||||
return angularJson['projects']?.[APPLICATION_OPTIONS.name]?.['architect'][
|
||||
e2eScript
|
||||
];
|
||||
return angularJson['projects']?.[SINGLE_APPLICATION_OPTIONS.name]?.[
|
||||
'architect'
|
||||
][e2eScript];
|
||||
}
|
||||
|
||||
export function getPackageJson(tree: UnitTestTree): {
|
||||
@ -59,8 +69,13 @@ export function getPackageJson(tree: UnitTestTree): {
|
||||
};
|
||||
}
|
||||
|
||||
export function getMultiProjectFile(file: string): string {
|
||||
return `/${WORKSPACE_OPTIONS.newProjectRoot}/${MULTI_APPLICATION_OPTIONS.name}/${file}`;
|
||||
}
|
||||
|
||||
export async function buildTestingTree(
|
||||
command: 'ng-add' | 'test',
|
||||
type: 'single' | 'multi' = 'single',
|
||||
userOptions?: Record<string, any>
|
||||
): Promise<UnitTestTree> {
|
||||
const runner = new SchematicTestRunner(
|
||||
@ -76,11 +91,27 @@ export async function buildTestingTree(
|
||||
let workingTree: UnitTestTree;
|
||||
|
||||
// Build workspace
|
||||
workingTree = await runner.runExternalSchematic(
|
||||
'@schematics/angular',
|
||||
'ng-new',
|
||||
APPLICATION_OPTIONS
|
||||
);
|
||||
if (type === 'single') {
|
||||
workingTree = await runner.runExternalSchematic(
|
||||
'@schematics/angular',
|
||||
'ng-new',
|
||||
SINGLE_APPLICATION_OPTIONS
|
||||
);
|
||||
} else {
|
||||
// Build workspace
|
||||
workingTree = await runner.runExternalSchematic(
|
||||
'@schematics/angular',
|
||||
'workspace',
|
||||
WORKSPACE_OPTIONS
|
||||
);
|
||||
// Build dummy application
|
||||
workingTree = await runner.runExternalSchematic(
|
||||
'@schematics/angular',
|
||||
'application',
|
||||
MULTI_APPLICATION_OPTIONS,
|
||||
workingTree
|
||||
);
|
||||
}
|
||||
|
||||
if (command !== 'ng-add') {
|
||||
// We want to create update the proper files with `ng-add`
|
||||
|
@ -20,11 +20,29 @@ const {join} = require('path');
|
||||
const {cwd} = require('process');
|
||||
|
||||
const isInit = process.argv.indexOf('--init') !== -1;
|
||||
const isMulti = process.argv.indexOf('--multi') !== -1;
|
||||
const isBuild = process.argv.indexOf('--build') !== -1;
|
||||
const isTest = process.argv.indexOf('--test') !== -1;
|
||||
const commands = {
|
||||
build: ['npm run build'],
|
||||
createSandbox: ['npx ng new sandbox --defaults'],
|
||||
createMultiWorkspace: [
|
||||
'ng new sandbox --create-application=false --directory=multi',
|
||||
],
|
||||
createMultiProjects: [
|
||||
{
|
||||
command: 'ng generate application core --style=css --routing=false',
|
||||
options: {
|
||||
cwd: join(cwd(), '/multi/'),
|
||||
},
|
||||
},
|
||||
{
|
||||
command: 'ng generate application admin --style=css --routing=false',
|
||||
options: {
|
||||
cwd: join(cwd(), '/multi/'),
|
||||
},
|
||||
},
|
||||
],
|
||||
runSchematics: [
|
||||
{
|
||||
command: 'npm run schematics',
|
||||
@ -51,7 +69,7 @@ const scripts = {
|
||||
// Runs the Puppeteer Ng-Schematics against the sandbox
|
||||
schematics:
|
||||
'npm run delete:file && npm run build:schematics && schematics ../:ng-add --dry-run=false',
|
||||
'schematics:spec':
|
||||
'schematics:test':
|
||||
'npm run build:schematics && schematics ../:test --dry-run=false',
|
||||
};
|
||||
/**
|
||||
@ -79,7 +97,7 @@ async function executeCommand(commands) {
|
||||
});
|
||||
|
||||
createProcess.on('error', message => {
|
||||
console.error(message);
|
||||
console.error(`Running ${toExecute} exited with error:`, message);
|
||||
reject(message);
|
||||
});
|
||||
|
||||
@ -96,9 +114,16 @@ async function executeCommand(commands) {
|
||||
|
||||
async function main() {
|
||||
if (isInit) {
|
||||
await executeCommand(commands.createSandbox);
|
||||
if (isMulti) {
|
||||
await executeCommand(commands.createMultiWorkspace);
|
||||
await executeCommand(commands.createMultiProjects);
|
||||
} else {
|
||||
await executeCommand(commands.createSandbox);
|
||||
}
|
||||
|
||||
const packageJsonFile = join(cwd(), '/sandbox/package.json');
|
||||
const directory = isMulti ? 'multi' : 'sandbox';
|
||||
|
||||
const packageJsonFile = join(cwd(), `/${directory}/package.json`);
|
||||
const packageJson = JSON.parse(await readFile(packageJsonFile));
|
||||
packageJson['scripts'] = {
|
||||
...packageJson['scripts'],
|
||||
|
@ -10,7 +10,7 @@
|
||||
},
|
||||
"packages/testserver": {},
|
||||
"packages/ng-schematics": {
|
||||
"release-as": "0.3.0"
|
||||
"release-as": "0.4.0"
|
||||
},
|
||||
"packages/browsers": {}
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user