diff options
Diffstat (limited to 'remote/test/puppeteer/packages/ng-schematics/src/schematics/e2e')
3 files changed, 170 insertions, 0 deletions
diff --git a/remote/test/puppeteer/packages/ng-schematics/src/schematics/e2e/files/common/e2e/tests/__name@dasherize__.__ext@dasherize__.ts.template b/remote/test/puppeteer/packages/ng-schematics/src/schematics/e2e/files/common/e2e/tests/__name@dasherize__.__ext@dasherize__.ts.template new file mode 100644 index 0000000000..ca90f258b8 --- /dev/null +++ b/remote/test/puppeteer/packages/ng-schematics/src/schematics/e2e/files/common/e2e/tests/__name@dasherize__.__ext@dasherize__.ts.template @@ -0,0 +1,18 @@ +<% if(testRunner == 'node') { %> +import * as assert from 'assert'; +import {describe, it} from 'node:test'; +<% } %><% if(testRunner == 'mocha') { %> +import * as assert from 'assert'; +<% } %> +import {setupBrowserHooks, getBrowserState} from './utils'; + +describe('<%= classify(name) %>', function () { + <% if(route) { %> + setupBrowserHooks('<%= route %>'); + <% } else { %> + setupBrowserHooks(); + <% } %> + it('', async function () { + const {page} = getBrowserState(); + }); +}); 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, + }, + } + ); + }; +} diff --git a/remote/test/puppeteer/packages/ng-schematics/src/schematics/e2e/schema.json b/remote/test/puppeteer/packages/ng-schematics/src/schematics/e2e/schema.json new file mode 100644 index 0000000000..7752c9ceef --- /dev/null +++ b/remote/test/puppeteer/packages/ng-schematics/src/schematics/e2e/schema.json @@ -0,0 +1,34 @@ +{ + "$schema": "http://json-schema.org/schema", + "$id": "Puppeteer", + "title": "Puppeteer E2E Schema", + "type": "object", + "properties": { + "name": { + "type": "string", + "alias": "n", + "$default": { + "$source": "argv", + "index": 0 + }, + "x-prompt": "Name for spec to be created:" + }, + "project": { + "type": "string", + "$default": { + "$source": "argv", + "index": 1 + }, + "alias": "p" + }, + "route": { + "type": "string", + "$default": { + "$source": "argv", + "index": 1 + }, + "alias": "r" + } + }, + "required": [] +} |