diff options
Diffstat (limited to 'remote/test/puppeteer/packages/ng-schematics/src/schematics/e2e/index.ts')
-rw-r--r-- | remote/test/puppeteer/packages/ng-schematics/src/schematics/e2e/index.ts | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/remote/test/puppeteer/packages/ng-schematics/src/schematics/e2e/index.ts b/remote/test/puppeteer/packages/ng-schematics/src/schematics/e2e/index.ts new file mode 100644 index 0000000000..cf1f634f94 --- /dev/null +++ b/remote/test/puppeteer/packages/ng-schematics/src/schematics/e2e/index.ts @@ -0,0 +1,118 @@ +/** + * @license + * Copyright 2023 Google Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +import { + chain, + type Rule, + type SchematicContext, + SchematicsException, + type Tree, +} from '@angular-devkit/schematics'; + +import {addCommonFiles} from '../utils/files.js'; +import {getApplicationProjects} from '../utils/json.js'; +import { + TestRunner, + type SchematicsSpec, + type AngularProject, + type PuppeteerSchematicsConfig, +} 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 e2e(userArgs: Record<string, string>): Rule { + const options = parseUserTestArgs(userArgs); + + return (tree: Tree, context: SchematicContext) => { + return chain([addE2EFile(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']; + } + if ('r' in userArgs) { + options['route'] = userArgs['r']; + } + + if (options['route'] && options['route'].startsWith('/')) { + options['route'] = options['route'].substring(1); + } + + return options as SchematicsSpec; +} + +function findTestingOption< + Property extends keyof PuppeteerSchematicsConfig['options'], +>( + [name, project]: [string, AngularProject | undefined], + property: Property +): PuppeteerSchematicsConfig['options'][Property] { + if (!project) { + throw new Error(`Project "${name}" not found.`); + } + + const e2e = project.architect?.e2e; + const puppeteer = project.architect?.puppeteer; + const builder = '@puppeteer/ng-schematics:puppeteer'; + + if (e2e?.builder === builder) { + return e2e.options[property]; + } else if (puppeteer?.builder === builder) { + return puppeteer.options[property]; + } + + throw new Error(`Can't find property "${property}" for project "${name}".`); +} + +function addE2EFile(options: SchematicsSpec): Rule { + return async (tree: Tree, context: SchematicContext) => { + context.logger.debug('Adding Spec file.'); + + const projects = getApplicationProjects(tree); + const projectNames = Object.keys(projects) as [string, ...string[]]; + const foundProject: [string, AngularProject | undefined] | undefined = + projectNames.length === 1 + ? [projectNames[0], projects[projectNames[0]]] + : Object.entries(projects).find(([name, project]) => { + return options.project + ? options.project === name + : project.root === ''; + }); + if (!foundProject) { + throw new SchematicsException( + `Project not found! Please run "ng generate @puppeteer/ng-schematics:test <Test> <Project>"` + ); + } + + const testRunner = findTestingOption(foundProject, 'testRunner'); + const port = findTestingOption(foundProject, 'port'); + + context.logger.debug('Creating Spec file.'); + + return addCommonFiles( + {[foundProject[0]]: foundProject[1]} as Record<string, AngularProject>, + { + options: { + name: options.name, + route: options.route, + testRunner, + // Node test runner does not support glob patterns + // It looks for files `*.test.js` + ext: testRunner === TestRunner.Node ? 'test' : 'e2e', + port, + }, + } + ); + }; +} |