From 35dc2d884052b27a3f9c70b8646f95743be7b84d Mon Sep 17 00:00:00 2001 From: Nikolay Vitkov <34244704+Lightning00Blade@users.noreply.github.com> Date: Fri, 18 Aug 2023 11:09:26 +0200 Subject: [PATCH] chore(ng-schematics): refactor away user-side complexity (#10750) --- docs/ng-schematics.md | 13 +-- packages/ng-schematics/README.md | 13 +-- .../src/builders/puppeteer/index.ts | 33 +++++- .../src/schematics/collection.json | 11 +- .../files/.puppeteerrc.mjs} | 2 +- .../src/schematics/config/index.ts | 44 +++++++ .../src/schematics/config/schema.json | 8 ++ ...@dasherize__.__ext@dasherize__.ts.template | 8 +- .../src/schematics/{test => e2e}/index.ts | 29 ++--- .../src/schematics/{test => e2e}/schema.json | 10 +- .../{node => common}/e2e/.gitignore.template | 0 .../tests/app.__ext@dasherize__.ts.template | 8 +- .../files/common/e2e/tests/utils.ts.template | 18 +-- .../files/common/e2e/tsconfig.json.template | 7 +- .../ng-add/files/jasmine/e2e/helpers/babel.js | 4 - .../files/jasmine/e2e/support/jasmine.json | 5 +- .../ng-add/files/jest/e2e/jest.config.js | 5 +- .../ng-add/files/mocha/e2e/.mocharc.js | 3 +- .../ng-add/files/mocha/e2e/babel.js | 4 - .../src/schematics/ng-add/index.ts | 80 +++---------- .../src/schematics/ng-add/schema.json | 22 +--- .../src/schematics/utils/files.ts | 62 +++++----- .../src/schematics/utils/packages.ts | 35 ++---- .../src/schematics/utils/types.ts | 13 ++- .../ng-schematics/test/src/config.spec.ts | 26 +++++ .../test/src/{test.spec.ts => e2e.spec.ts} | 14 +-- .../ng-schematics/test/src/ng-add.spec.ts | 108 ++++-------------- packages/ng-schematics/test/src/utils.ts | 18 ++- 28 files changed, 294 insertions(+), 309 deletions(-) rename packages/ng-schematics/src/schematics/{ng-add/files/base/.puppeteerrc.cjs => config/files/.puppeteerrc.mjs} (71%) create mode 100644 packages/ng-schematics/src/schematics/config/index.ts create mode 100644 packages/ng-schematics/src/schematics/config/schema.json rename packages/ng-schematics/src/schematics/{test => e2e}/files/common/e2e/tests/__name@dasherize__.__ext@dasherize__.ts.template (67%) rename packages/ng-schematics/src/schematics/{test => e2e}/index.ts (83%) rename packages/ng-schematics/src/schematics/{test => e2e}/schema.json (72%) rename packages/ng-schematics/src/schematics/ng-add/files/{node => common}/e2e/.gitignore.template (100%) delete mode 100644 packages/ng-schematics/src/schematics/ng-add/files/jasmine/e2e/helpers/babel.js delete mode 100644 packages/ng-schematics/src/schematics/ng-add/files/mocha/e2e/babel.js create mode 100644 packages/ng-schematics/test/src/config.spec.ts rename packages/ng-schematics/test/src/{test.spec.ts => e2e.spec.ts} (77%) diff --git a/docs/ng-schematics.md b/docs/ng-schematics.md index da31c37db8d..af5f3b7183e 100644 --- a/docs/ng-schematics.md +++ b/docs/ng-schematics.md @@ -14,7 +14,7 @@ ng add @puppeteer/ng-schematics Or you can use the same command followed by the [options](#options) below. -Currently, this schematic supports the following test frameworks: +Currently, this schematic supports the following test runners: - [**Jasmine**](https://jasmine.github.io/) - [**Jest**](https://jestjs.io/) @@ -31,12 +31,9 @@ ng e2e When adding schematics to your project you can to provide following options: -| Option | Description | Value | Required | -| -------------------- | ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | -------- | -| `--isDefaultTester` | When true, replaces default `ng e2e` command. | `boolean` | `true` | -| `--exportConfig` | When true, creates an empty [Puppeteer configuration](https://pptr.dev/guides/configuration) file. (`.puppeteerrc.cjs`) | `boolean` | `true` | -| `--testingFramework` | The testing framework to install along side Puppeteer. | `"jasmine"`, `"jest"`, `"mocha"`, `"node"` | `true` | -| `--port` | The port to spawn server for E2E. If default is used `ng serve` and `ng e2e` will not run side-by-side. | `number` | `4200` | +| Option | Description | Value | Required | +| -------------- | ------------------------------------------------------ | ------------------------------------------ | -------- | +| `--testRunner` | The testing framework to install along side Puppeteer. | `"jasmine"`, `"jest"`, `"mocha"`, `"node"` | `true` | ## Creating a single test file @@ -59,7 +56,7 @@ Update either `e2e` or `puppeteer` (depending on the initial setup) to: "options": { "commands": [...], "devServerTarget": "sandbox:serve", - "testingFramework": "", + "testRunner": "", "port": 8080 }, ... diff --git a/packages/ng-schematics/README.md b/packages/ng-schematics/README.md index da31c37db8d..af5f3b7183e 100644 --- a/packages/ng-schematics/README.md +++ b/packages/ng-schematics/README.md @@ -14,7 +14,7 @@ ng add @puppeteer/ng-schematics Or you can use the same command followed by the [options](#options) below. -Currently, this schematic supports the following test frameworks: +Currently, this schematic supports the following test runners: - [**Jasmine**](https://jasmine.github.io/) - [**Jest**](https://jestjs.io/) @@ -31,12 +31,9 @@ ng e2e When adding schematics to your project you can to provide following options: -| Option | Description | Value | Required | -| -------------------- | ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ | -------- | -| `--isDefaultTester` | When true, replaces default `ng e2e` command. | `boolean` | `true` | -| `--exportConfig` | When true, creates an empty [Puppeteer configuration](https://pptr.dev/guides/configuration) file. (`.puppeteerrc.cjs`) | `boolean` | `true` | -| `--testingFramework` | The testing framework to install along side Puppeteer. | `"jasmine"`, `"jest"`, `"mocha"`, `"node"` | `true` | -| `--port` | The port to spawn server for E2E. If default is used `ng serve` and `ng e2e` will not run side-by-side. | `number` | `4200` | +| Option | Description | Value | Required | +| -------------- | ------------------------------------------------------ | ------------------------------------------ | -------- | +| `--testRunner` | The testing framework to install along side Puppeteer. | `"jasmine"`, `"jest"`, `"mocha"`, `"node"` | `true` | ## Creating a single test file @@ -59,7 +56,7 @@ Update either `e2e` or `puppeteer` (depending on the initial setup) to: "options": { "commands": [...], "devServerTarget": "sandbox:serve", - "testingFramework": "", + "testRunner": "", "port": 8080 }, ... diff --git a/packages/ng-schematics/src/builders/puppeteer/index.ts b/packages/ng-schematics/src/builders/puppeteer/index.ts index 30cb126b277..2aaeed5b9c5 100644 --- a/packages/ng-schematics/src/builders/puppeteer/index.ts +++ b/packages/ng-schematics/src/builders/puppeteer/index.ts @@ -9,6 +9,8 @@ import { } from '@angular-devkit/architect'; import {JsonObject} from '@angular-devkit/core'; +import {TestRunner} from '../../schematics/utils/types.js'; + import {PuppeteerBuilderOptions} from './types.js'; const terminalStyles = { @@ -39,13 +41,35 @@ function getExecutable(command: string[]) { }; } +function updateExecutablePath(command: string, root?: string) { + let path = 'node_modules/.bin/'; + if (root && root !== '' && command === TestRunner.Node) { + const nested = root + .split('/') + .map(() => { + return '../'; + }) + .join(''); + path = `${nested}${path}${command}`; + } else { + path = `./${path}${command}`; + } + + return path; +} + async function executeCommand(context: BuilderContext, command: string[]) { + let project: JsonObject; + if (context.target) { + project = await context.getProjectMetadata(context.target.project); + command[0] = updateExecutablePath(command[0]!, String(project['root'])); + } + await new Promise(async (resolve, reject) => { context.logger.debug(`Trying to execute command - ${command.join(' ')}.`); const {executable, args, error} = getExecutable(command); let path = context.workspaceRoot; if (context.target) { - const project = await context.getProjectMetadata(context.target.project); path = `${path}/${project['root']}`; } @@ -123,8 +147,13 @@ async function executeE2ETest( try { server = await startServer(options, context); + const commands = options.commands; + + message('\n Building tests 🛠️ ... \n', context); + await executeCommand(context, [`tsc`, '-p', 'e2e/tsconfig.json']); + message('\n Running tests 🧪 ... \n', context); - for (const command of options.commands) { + for (const command of commands) { await executeCommand(context, command); } diff --git a/packages/ng-schematics/src/schematics/collection.json b/packages/ng-schematics/src/schematics/collection.json index ca3b2997364..00bede45e58 100644 --- a/packages/ng-schematics/src/schematics/collection.json +++ b/packages/ng-schematics/src/schematics/collection.json @@ -6,10 +6,15 @@ "factory": "./ng-add/index#ngAdd", "schema": "./ng-add/schema.json" }, - "test": { + "e2e": { "description": "Create a single test file", - "factory": "./test/index#test", - "schema": "./test/schema.json" + "factory": "./e2e/index#e2e", + "schema": "./e2e/schema.json" + }, + "config": { + "description": "Eject Puppeteer config file", + "factory": "./config/index#config", + "schema": "./config/schema.json" } } } diff --git a/packages/ng-schematics/src/schematics/ng-add/files/base/.puppeteerrc.cjs b/packages/ng-schematics/src/schematics/config/files/.puppeteerrc.mjs similarity index 71% rename from packages/ng-schematics/src/schematics/ng-add/files/base/.puppeteerrc.cjs rename to packages/ng-schematics/src/schematics/config/files/.puppeteerrc.mjs index 04f3f0d8329..0da14a80d85 100644 --- a/packages/ng-schematics/src/schematics/ng-add/files/base/.puppeteerrc.cjs +++ b/packages/ng-schematics/src/schematics/config/files/.puppeteerrc.mjs @@ -1,4 +1,4 @@ /** * @type {import("puppeteer").Configuration} */ -module.exports = {}; +export {}; diff --git a/packages/ng-schematics/src/schematics/config/index.ts b/packages/ng-schematics/src/schematics/config/index.ts new file mode 100644 index 00000000000..6026212a330 --- /dev/null +++ b/packages/ng-schematics/src/schematics/config/index.ts @@ -0,0 +1,44 @@ +/** + * 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 {chain, Rule, SchematicContext, Tree} from '@angular-devkit/schematics'; + +import {addFilesSingle} from '../utils/files.js'; +import {TestRunner, 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 config(): Rule { + return (tree: Tree, context: SchematicContext) => { + return chain([addPuppeteerConfig()])(tree, context); + }; +} + +function addPuppeteerConfig(): Rule { + return (tree: Tree, context: SchematicContext) => { + context.logger.debug('Adding Puppeteer config file.'); + + return addFilesSingle(tree, context, '', {root: ''} as AngularProject, { + // No-op here to fill types + options: { + testRunner: TestRunner.Jasmine, + port: 4200, + }, + applyPath: './files', + relativeToWorkspacePath: `/`, + }); + }; +} diff --git a/packages/ng-schematics/src/schematics/config/schema.json b/packages/ng-schematics/src/schematics/config/schema.json new file mode 100644 index 00000000000..8d45751bb19 --- /dev/null +++ b/packages/ng-schematics/src/schematics/config/schema.json @@ -0,0 +1,8 @@ +{ + "$schema": "http://json-schema.org/schema", + "$id": "Puppeteer", + "title": "Puppeteer Config Schema", + "type": "object", + "properties": {}, + "required": [] +} diff --git a/packages/ng-schematics/src/schematics/test/files/common/e2e/tests/__name@dasherize__.__ext@dasherize__.ts.template b/packages/ng-schematics/src/schematics/e2e/files/common/e2e/tests/__name@dasherize__.__ext@dasherize__.ts.template similarity index 67% rename from packages/ng-schematics/src/schematics/test/files/common/e2e/tests/__name@dasherize__.__ext@dasherize__.ts.template rename to packages/ng-schematics/src/schematics/e2e/files/common/e2e/tests/__name@dasherize__.__ext@dasherize__.ts.template index 8b20ee2e626..ca90f258b8f 100644 --- a/packages/ng-schematics/src/schematics/test/files/common/e2e/tests/__name@dasherize__.__ext@dasherize__.ts.template +++ b/packages/ng-schematics/src/schematics/e2e/files/common/e2e/tests/__name@dasherize__.__ext@dasherize__.ts.template @@ -1,13 +1,17 @@ -<% if(testingFramework == 'node') { %> +<% if(testRunner == 'node') { %> import * as assert from 'assert'; import {describe, it} from 'node:test'; -<% } %><% if(testingFramework == 'mocha') { %> +<% } %><% 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/packages/ng-schematics/src/schematics/test/index.ts b/packages/ng-schematics/src/schematics/e2e/index.ts similarity index 83% rename from packages/ng-schematics/src/schematics/test/index.ts rename to packages/ng-schematics/src/schematics/e2e/index.ts index 31ff1fe189c..8316b9bc810 100644 --- a/packages/ng-schematics/src/schematics/test/index.ts +++ b/packages/ng-schematics/src/schematics/e2e/index.ts @@ -25,19 +25,19 @@ import { import {addCommonFiles} from '../utils/files.js'; import {getAngularConfig} from '../utils/json.js'; import { - TestingFramework, + TestRunner, SchematicsSpec, - SchematicsOptions, AngularProject, + 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 test(userArgs: Record): Rule { +export function e2e(userArgs: Record): Rule { const options = parseUserTestArgs(userArgs); return (tree: Tree, context: SchematicContext) => { - return chain([addSpecFile(options)])(tree, context); + return chain([addE2EFile(options)])(tree, context); }; } @@ -51,14 +51,19 @@ function parseUserTestArgs(userArgs: Record): SchematicsSpec { if ('n' in userArgs) { options['name'] = userArgs['n']; } + if ('r' in userArgs) { + options['route'] = userArgs['n']; + } return options as SchematicsSpec; } -function findTestingOption( +function findTestingOption< + Property extends keyof PuppeteerSchematicsConfig['options'], +>( [name, project]: [string, AngularProject | undefined], property: Property -): SchematicsOptions[Property] { +): PuppeteerSchematicsConfig['options'][Property] { if (!project) { throw new Error(`Project "${name}" not found.`); } @@ -76,7 +81,7 @@ function findTestingOption( throw new Error(`Can't find property "${property}" for project "${name}".`); } -function addSpecFile(options: SchematicsSpec): Rule { +function addE2EFile(options: SchematicsSpec): Rule { return async (tree: Tree, context: SchematicContext) => { context.logger.debug('Adding Spec file.'); @@ -96,10 +101,7 @@ function addSpecFile(options: SchematicsSpec): Rule { ); } - const testingFramework = findTestingOption( - foundProject, - 'testingFramework' - ); + const testRunner = findTestingOption(foundProject, 'testRunner'); const port = findTestingOption(foundProject, 'port'); context.logger.debug('Creating Spec file.'); @@ -111,10 +113,11 @@ function addSpecFile(options: SchematicsSpec): Rule { { options: { name: options.name, - testingFramework, + route: options.route, + testRunner, // Node test runner does not support glob patterns // It looks for files `*.test.js` - ext: testingFramework === TestingFramework.Node ? 'test' : 'e2e', + ext: testRunner === TestRunner.Node ? 'test' : 'e2e', port, }, } diff --git a/packages/ng-schematics/src/schematics/test/schema.json b/packages/ng-schematics/src/schematics/e2e/schema.json similarity index 72% rename from packages/ng-schematics/src/schematics/test/schema.json rename to packages/ng-schematics/src/schematics/e2e/schema.json index 0a66cce128b..7752c9ceef3 100644 --- a/packages/ng-schematics/src/schematics/test/schema.json +++ b/packages/ng-schematics/src/schematics/e2e/schema.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/schema", "$id": "Puppeteer", - "title": "Puppeteer Spec Schema", + "title": "Puppeteer E2E Schema", "type": "object", "properties": { "name": { @@ -20,6 +20,14 @@ "index": 1 }, "alias": "p" + }, + "route": { + "type": "string", + "$default": { + "$source": "argv", + "index": 1 + }, + "alias": "r" } }, "required": [] diff --git a/packages/ng-schematics/src/schematics/ng-add/files/node/e2e/.gitignore.template b/packages/ng-schematics/src/schematics/ng-add/files/common/e2e/.gitignore.template similarity index 100% rename from packages/ng-schematics/src/schematics/ng-add/files/node/e2e/.gitignore.template rename to packages/ng-schematics/src/schematics/ng-add/files/common/e2e/.gitignore.template diff --git a/packages/ng-schematics/src/schematics/ng-add/files/common/e2e/tests/app.__ext@dasherize__.ts.template b/packages/ng-schematics/src/schematics/ng-add/files/common/e2e/tests/app.__ext@dasherize__.ts.template index eec01a61919..1fdf924160a 100644 --- a/packages/ng-schematics/src/schematics/ng-add/files/common/e2e/tests/app.__ext@dasherize__.ts.template +++ b/packages/ng-schematics/src/schematics/ng-add/files/common/e2e/tests/app.__ext@dasherize__.ts.template @@ -1,7 +1,7 @@ -<% if(testingFramework == 'node') { %> +<% if(testRunner == 'node') { %> import * as assert from 'assert'; import {describe, it} from 'node:test'; -<% } %><% if(testingFramework == 'mocha') { %> +<% } %><% if(testRunner == 'mocha') { %> import * as assert from 'assert'; <% } %> import {setupBrowserHooks, getBrowserState} from './utils'; @@ -12,9 +12,9 @@ describe('App test', function () { const {page} = getBrowserState(); const element = await page.waitForSelector('text/<%= project %> app is running!'); -<% if(testingFramework == 'jasmine' || testingFramework == 'jest') { %> +<% if(testRunner == 'jasmine' || testRunner == 'jest') { %> expect(element).not.toBeNull(); -<% } %><% if(testingFramework == 'mocha' || testingFramework == 'node') { %> +<% } %><% if(testRunner == 'mocha' || testRunner == 'node') { %> assert.ok(element); <% } %> }); diff --git a/packages/ng-schematics/src/schematics/ng-add/files/common/e2e/tests/utils.ts.template b/packages/ng-schematics/src/schematics/ng-add/files/common/e2e/tests/utils.ts.template index 2fc3e007cb3..cd00dc3ab0c 100644 --- a/packages/ng-schematics/src/schematics/ng-add/files/common/e2e/tests/utils.ts.template +++ b/packages/ng-schematics/src/schematics/ng-add/files/common/e2e/tests/utils.ts.template @@ -1,4 +1,4 @@ -<% if(testingFramework == 'node') { %> +<% if(testRunner == 'node') { %> import {before, beforeEach, after, afterEach} from 'node:test'; <% } %> import * as puppeteer from 'puppeteer'; @@ -7,33 +7,35 @@ const baseUrl = '<%= baseUrl %>'; let browser: puppeteer.Browser; let page: puppeteer.Page; -export function setupBrowserHooks(): void { -<% if(testingFramework == 'jasmine' || testingFramework == 'jest') { %> +export function setupBrowserHooks(path = '/'): void { +<% if(testRunner == 'jasmine' || testRunner == 'jest') { %> beforeAll(async () => { browser = await puppeteer.launch({ headless: 'new' }); }); -<% } %><% if(testingFramework == 'mocha' || testingFramework == 'node') { %> +<% } %><% if(testRunner == 'mocha' || testRunner == 'node') { %> before(async () => { - browser = await puppeteer.launch(); + browser = await puppeteer.launch({ + headless: 'new' + }); }); <% } %> beforeEach(async () => { page = await browser.newPage(); - await page.goto(baseUrl); + await page.goto(`${baseUrl}${path}`); }); afterEach(async () => { await page.close(); }); -<% if(testingFramework == 'jasmine' || testingFramework == 'jest') { %> +<% if(testRunner == 'jasmine' || testRunner == 'jest') { %> afterAll(async () => { await browser.close(); }); -<% } %><% if(testingFramework == 'mocha' || testingFramework == 'node') { %> +<% } %><% if(testRunner == 'mocha' || testRunner == 'node') { %> after(async () => { await browser.close(); }); diff --git a/packages/ng-schematics/src/schematics/ng-add/files/common/e2e/tsconfig.json.template b/packages/ng-schematics/src/schematics/ng-add/files/common/e2e/tsconfig.json.template index 583e5ed4af7..38501b89efa 100644 --- a/packages/ng-schematics/src/schematics/ng-add/files/common/e2e/tsconfig.json.template +++ b/packages/ng-schematics/src/schematics/ng-add/files/common/e2e/tsconfig.json.template @@ -1,11 +1,10 @@ { "extends": "<%= tsConfigPath %>", - "compilerOptions": {<% if(testingFramework == 'jest') { %> - "esModuleInterop": true,<% } %><% if(testingFramework == 'node') { %> + "compilerOptions": { "module": "CommonJS", "rootDir": "tests/", - "outDir": "build/",<% } %> - "types": ["<%= testingFramework %>"] + "outDir": "build/", + "types": ["<%= testRunner %>"] }, "include": ["tests/**/*.ts"] } diff --git a/packages/ng-schematics/src/schematics/ng-add/files/jasmine/e2e/helpers/babel.js b/packages/ng-schematics/src/schematics/ng-add/files/jasmine/e2e/helpers/babel.js deleted file mode 100644 index 06259b39c84..00000000000 --- a/packages/ng-schematics/src/schematics/ng-add/files/jasmine/e2e/helpers/babel.js +++ /dev/null @@ -1,4 +0,0 @@ -require('@babel/register')({ - extensions: ['.js', '.ts'], - presets: ['@babel/preset-env', '@babel/preset-typescript'], -}); diff --git a/packages/ng-schematics/src/schematics/ng-add/files/jasmine/e2e/support/jasmine.json b/packages/ng-schematics/src/schematics/ng-add/files/jasmine/e2e/support/jasmine.json index 7100e102f10..ad5dc6fbce9 100644 --- a/packages/ng-schematics/src/schematics/ng-add/files/jasmine/e2e/support/jasmine.json +++ b/packages/ng-schematics/src/schematics/ng-add/files/jasmine/e2e/support/jasmine.json @@ -1,8 +1,9 @@ { "spec_dir": "e2e", - "spec_files": ["**/*[eE]2[eE].ts"], - "helpers": ["helpers/babel.js", "helpers/**/*.{js|ts}"], + "spec_files": ["**/*[eE]2[eE].js"], + "helpers": ["helpers/**/*.?(m)js"], "env": { + "failSpecWithNoExpectations": true, "stopSpecOnExpectationFailure": false, "random": true } diff --git a/packages/ng-schematics/src/schematics/ng-add/files/jest/e2e/jest.config.js b/packages/ng-schematics/src/schematics/ng-add/files/jest/e2e/jest.config.js index 99cc594c973..ca6f51dd9dc 100644 --- a/packages/ng-schematics/src/schematics/ng-add/files/jest/e2e/jest.config.js +++ b/packages/ng-schematics/src/schematics/ng-add/files/jest/e2e/jest.config.js @@ -3,9 +3,8 @@ * https://jestjs.io/docs/configuration */ -/** @type {import('ts-jest').JestConfigWithTsJest} */ +/** @type {import('jest').Config} */ module.exports = { - testMatch: ['/tests/**/?(*.)+(e2e).[tj]s?(x)'], - preset: 'ts-jest', + testMatch: ['/tests/**/?(*.)+(e2e).js?(x)'], testEnvironment: 'node', }; diff --git a/packages/ng-schematics/src/schematics/ng-add/files/mocha/e2e/.mocharc.js b/packages/ng-schematics/src/schematics/ng-add/files/mocha/e2e/.mocharc.js index 63ca85e3eb5..09e0f7382ea 100644 --- a/packages/ng-schematics/src/schematics/ng-add/files/mocha/e2e/.mocharc.js +++ b/packages/ng-schematics/src/schematics/ng-add/files/mocha/e2e/.mocharc.js @@ -1,4 +1,3 @@ module.exports = { - file: ['e2e/babel.js'], - spec: './e2e/tests/**/*.e2e.ts', + spec: './e2e/tests/**/*.e2e.js', }; diff --git a/packages/ng-schematics/src/schematics/ng-add/files/mocha/e2e/babel.js b/packages/ng-schematics/src/schematics/ng-add/files/mocha/e2e/babel.js deleted file mode 100644 index 06259b39c84..00000000000 --- a/packages/ng-schematics/src/schematics/ng-add/files/mocha/e2e/babel.js +++ /dev/null @@ -1,4 +0,0 @@ -require('@babel/register')({ - extensions: ['.js', '.ts'], - presets: ['@babel/preset-env', '@babel/preset-typescript'], -}); diff --git a/packages/ng-schematics/src/schematics/ng-add/index.ts b/packages/ng-schematics/src/schematics/ng-add/index.ts index 7e605a825ca..ac0a388c64e 100644 --- a/packages/ng-schematics/src/schematics/ng-add/index.ts +++ b/packages/ng-schematics/src/schematics/ng-add/index.ts @@ -21,9 +21,9 @@ import {concatMap, map, scan} from 'rxjs/operators'; import { addCommonFiles as addCommonFilesHelper, - addFilesSingle, addFrameworkFiles, getNgCommandName, + hasE2ETester, } from '../utils/files.js'; import {getAngularConfig} from '../utils/json.js'; import { @@ -35,55 +35,24 @@ import { type NodePackage, updateAngularJsonScripts, } from '../utils/packages.js'; -import { - TestingFramework, - type SchematicsOptions, - AngularProject, -} from '../utils/types.js'; +import {TestRunner, type SchematicsOptions} from '../utils/types.js'; + +const DEFAULT_PORT = 4200; // You don't have to export the function as default. You can also have more than one rule // factory per file. -export function ngAdd(userArgs: Record): Rule { - const options = parseUserAddArgs(userArgs); - +export function ngAdd(options: SchematicsOptions): Rule { return (tree: Tree, context: SchematicContext) => { return chain([ addDependencies(options), - addPuppeteerConfig(options), addCommonFiles(options), addOtherFiles(options), - updateScripts(options), + updateScripts(), updateAngularConfig(options), ])(tree, context); }; } -function parseUserAddArgs(userArgs: Record): SchematicsOptions { - const options: Partial = { - ...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"'); @@ -108,15 +77,15 @@ function addDependencies(options: SchematicsOptions): Rule { }; } -function updateScripts(options: SchematicsOptions): Rule { +function updateScripts(): Rule { return (tree: Tree, context: SchematicContext): Tree => { context.logger.debug('Updating "package.json" scripts'); - const angularJson = getAngularConfig(tree); - const projects = Object.keys(angularJson['projects']); + const {projects} = getAngularConfig(tree); + const projectsKeys = Object.keys(projects); - if (projects.length === 1) { - const name = getNgCommandName(options); - const prefix = options.isDefaultTester ? '' : `run ${projects[0]}:`; + if (projectsKeys.length === 1) { + const name = getNgCommandName(projects); + const prefix = hasE2ETester(projects) ? `run ${projectsKeys[0]}:` : ''; return addPackageJsonScripts(tree, [ { name, @@ -128,22 +97,6 @@ function updateScripts(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.'); @@ -152,8 +105,8 @@ function addCommonFiles(options: SchematicsOptions): Rule { return addCommonFilesHelper(tree, context, projects, { options: { ...options, - ext: - options.testingFramework === TestingFramework.Node ? 'test' : 'e2e', + port: DEFAULT_PORT, + ext: options.testRunner === TestRunner.Node ? 'test' : 'e2e', }, }); }; @@ -165,7 +118,10 @@ function addOtherFiles(options: SchematicsOptions): Rule { const {projects} = getAngularConfig(tree); return addFrameworkFiles(tree, context, projects, { - options, + options: { + ...options, + port: DEFAULT_PORT, + }, }); }; } diff --git a/packages/ng-schematics/src/schematics/ng-add/schema.json b/packages/ng-schematics/src/schematics/ng-add/schema.json index 79e42477c4c..0fa581f1a71 100644 --- a/packages/ng-schematics/src/schematics/ng-add/schema.json +++ b/packages/ng-schematics/src/schematics/ng-add/schema.json @@ -4,25 +4,13 @@ "title": "Puppeteer Install Schema", "type": "object", "properties": { - "isDefaultTester": { - "type": "boolean", - "default": true, - "alias": "d", - "x-prompt": "Use Puppeteer as default `ng e2e` command?" - }, - "exportConfig": { - "type": "boolean", - "default": false, - "alias": "c", - "x-prompt": "Export default Puppeteer config file?" - }, - "testingFramework": { + "testRunner": { "type": "string", "enum": ["jasmine", "jest", "mocha", "node"], "default": "jasmine", "alias": "t", "x-prompt": { - "message": "With what Testing Library do you wish to integrate?", + "message": "Which test runners do you wish to use?", "type": "list", "items": [ { @@ -43,12 +31,6 @@ } ] } - }, - "port": { - "type": ["number"], - "default": 4200, - "alias": "p", - "x-prompt": "On which port to spawn test server on?" } }, "required": [] diff --git a/packages/ng-schematics/src/schematics/utils/files.ts b/packages/ng-schematics/src/schematics/utils/files.ts index 8ed896b92d4..d73f15b2044 100644 --- a/packages/ng-schematics/src/schematics/utils/files.ts +++ b/packages/ng-schematics/src/schematics/utils/files.ts @@ -28,15 +28,16 @@ import { url, } from '@angular-devkit/schematics'; -import {AngularProject, SchematicsOptions, TestingFramework} from './types.js'; +import {AngularProject, SchematicsOptions, TestRunner} from './types.js'; export interface FilesOptions { options: { - testingFramework: TestingFramework; + testRunner: TestRunner; port: number; name?: string; exportConfig?: boolean; ext?: string; + route?: string; }; applyPath: string; relativeToWorkspacePath: string; @@ -137,50 +138,41 @@ export function addFrameworkFiles( projects: Record, filesOptions: Omit ): any { - const testingFramework = filesOptions.options.testingFramework; + const testRunner = filesOptions.options.testRunner; const options: FilesOptions = { ...filesOptions, - applyPath: `./files/${testingFramework}`, + applyPath: `./files/${testRunner}`, relativeToWorkspacePath: `/`, }; return addFilesToProjects(tree, context, projects, options); } -export function getScriptFromOptions( - options: SchematicsOptions, - root?: string -): string[][] { - let path = 'node_modules/.bin'; - if (root && root !== '') { - const nested = root - .split('/') - .map(() => { - return '../'; - }) - .join(''); - path = `${nested}${path}`; - } else { - path = `./${path}`; - } - - switch (options.testingFramework) { - case TestingFramework.Jasmine: - return [[`${path}/jasmine`, '--config=./e2e/support/jasmine.json']]; - case TestingFramework.Jest: - return [[`${path}/jest`, '-c', 'e2e/jest.config.js']]; - case TestingFramework.Mocha: - return [[`${path}/mocha`, '--config=./e2e/.mocharc.js']]; - case TestingFramework.Node: - return [ - [`${path}/tsc`, '-p', 'e2e/tsconfig.json'], - ['node', '--test', '--test-reporter', 'spec', 'e2e/build/'], - ]; +export function getScriptFromOptions(options: SchematicsOptions): string[][] { + switch (options.testRunner) { + case TestRunner.Jasmine: + return [[`jasmine`, '--config=./e2e/support/jasmine.json']]; + case TestRunner.Jest: + return [[`jest`, '-c', 'e2e/jest.config.js']]; + case TestRunner.Mocha: + return [[`mocha`, '--config=./e2e/.mocharc.js']]; + case TestRunner.Node: + return [['node', '--test', '--test-reporter', 'spec', 'e2e/build/']]; } } -export function getNgCommandName(options: SchematicsOptions): string { - if (options.isDefaultTester) { +export function hasE2ETester( + projects: Record +): boolean { + return Object.values(projects).some((project: AngularProject) => { + return Boolean(project.architect?.e2e); + }); +} + +export function getNgCommandName( + projects: Record +): string { + if (!hasE2ETester(projects)) { return 'e2e'; } return 'puppeteer'; diff --git a/packages/ng-schematics/src/schematics/utils/packages.ts b/packages/ng-schematics/src/schematics/utils/packages.ts index 953be74a898..225f621dd6a 100644 --- a/packages/ng-schematics/src/schematics/utils/packages.ts +++ b/packages/ng-schematics/src/schematics/utils/packages.ts @@ -24,7 +24,7 @@ import { getJsonFileAsObject, getObjectAsJson, } from './json.js'; -import {SchematicsOptions, TestingFramework} from './types.js'; +import {SchematicsOptions, TestRunner} from './types.js'; export interface NodePackage { name: string; version: string; @@ -115,24 +115,18 @@ export function getDependenciesFromOptions( options: SchematicsOptions ): string[] { const dependencies = ['puppeteer']; - const babelPackages = [ - '@babel/core', - '@babel/register', - '@babel/preset-env', - '@babel/preset-typescript', - ]; - switch (options.testingFramework) { - case TestingFramework.Jasmine: - dependencies.push('jasmine', ...babelPackages); + switch (options.testRunner) { + case TestRunner.Jasmine: + dependencies.push('jasmine'); break; - case TestingFramework.Jest: - dependencies.push('jest', '@types/jest', 'ts-jest'); + case TestRunner.Jest: + dependencies.push('jest', '@types/jest'); break; - case TestingFramework.Mocha: - dependencies.push('mocha', '@types/mocha', ...babelPackages); + case TestRunner.Mocha: + dependencies.push('mocha', '@types/mocha'); break; - case TestingFramework.Node: + case TestRunner.Node: dependencies.push('@types/node'); break; } @@ -168,14 +162,10 @@ export function updateAngularJsonScripts( overwrite = true ): Tree { const angularJson = getAngularConfig(tree); - const name = getNgCommandName(options); - const port = options.port !== 4200 ? Number(options.port) : undefined; + const name = getNgCommandName(angularJson.projects); Object.keys(angularJson['projects']).forEach(project => { - const commands = getScriptFromOptions( - options, - angularJson['projects'][project]!.root - ); + const commands = getScriptFromOptions(options); const e2eScript = [ { name, @@ -184,8 +174,7 @@ export function updateAngularJsonScripts( options: { commands, devServerTarget: `${project}:serve`, - testingFramework: options.testingFramework, - port, + testRunner: options.testRunner, }, configurations: { production: { diff --git a/packages/ng-schematics/src/schematics/utils/types.ts b/packages/ng-schematics/src/schematics/utils/types.ts index 7b6f251b0a2..f3e3eb6d587 100644 --- a/packages/ng-schematics/src/schematics/utils/types.ts +++ b/packages/ng-schematics/src/schematics/utils/types.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -export enum TestingFramework { +export enum TestRunner { Jasmine = 'jasmine', Jest = 'jest', Mocha = 'mocha', @@ -22,15 +22,15 @@ export enum TestingFramework { } export interface SchematicsOptions { - isDefaultTester: boolean; - exportConfig: boolean; - testingFramework: TestingFramework; - port: number; + testRunner: TestRunner; } export interface PuppeteerSchematicsConfig { builder: string; - options: SchematicsOptions; + options: { + port: number; + testRunner: TestRunner; + }; } export interface AngularProject { root: string; @@ -46,4 +46,5 @@ export interface AngularJson { export interface SchematicsSpec { name: string; project?: string; + route?: string; } diff --git a/packages/ng-schematics/test/src/config.spec.ts b/packages/ng-schematics/test/src/config.spec.ts new file mode 100644 index 00000000000..da1a56de175 --- /dev/null +++ b/packages/ng-schematics/test/src/config.spec.ts @@ -0,0 +1,26 @@ +import expect from 'expect'; + +import { + buildTestingTree, + getMultiProjectFile, + setupHttpHooks, +} from './utils.js'; + +describe('@puppeteer/ng-schematics: config', () => { + setupHttpHooks(); + + describe('Single Project', () => { + it('should create default file', async () => { + const tree = await buildTestingTree('config', 'single'); + expect(tree.files).toContain('/.puppeteerrc.mjs'); + }); + }); + + describe('Multi projects', () => { + it('should create default file', async () => { + const tree = await buildTestingTree('config', 'multi'); + expect(tree.files).toContain('/.puppeteerrc.mjs'); + expect(tree.files).not.toContain(getMultiProjectFile('.puppeteerrc.mjs')); + }); + }); +}); diff --git a/packages/ng-schematics/test/src/test.spec.ts b/packages/ng-schematics/test/src/e2e.spec.ts similarity index 77% rename from packages/ng-schematics/test/src/test.spec.ts rename to packages/ng-schematics/test/src/e2e.spec.ts index 8b38b5e44e2..f5c989df21d 100644 --- a/packages/ng-schematics/test/src/test.spec.ts +++ b/packages/ng-schematics/test/src/e2e.spec.ts @@ -6,12 +6,12 @@ import { setupHttpHooks, } from './utils.js'; -describe('@puppeteer/ng-schematics: test', () => { +describe('@puppeteer/ng-schematics: e2e', () => { setupHttpHooks(); describe('Single Project', () => { it('should create default file', async () => { - const tree = await buildTestingTree('test', 'single', { + const tree = await buildTestingTree('e2e', 'single', { name: 'myTest', }); expect(tree.files).toContain('/e2e/tests/my-test.e2e.ts'); @@ -19,9 +19,9 @@ describe('@puppeteer/ng-schematics: test', () => { }); it('should create Node file', async () => { - const tree = await buildTestingTree('test', 'single', { + const tree = await buildTestingTree('e2e', 'single', { name: 'myTest', - testingFramework: 'node', + testRunner: 'node', }); expect(tree.files).not.toContain('/e2e/tests/my-test.e2e.ts'); expect(tree.files).toContain('/e2e/tests/my-test.test.ts'); @@ -30,7 +30,7 @@ describe('@puppeteer/ng-schematics: test', () => { describe('Multi projects', () => { it('should create default file', async () => { - const tree = await buildTestingTree('test', 'multi', { + const tree = await buildTestingTree('e2e', 'multi', { name: 'myTest', }); expect(tree.files).toContain( @@ -42,9 +42,9 @@ describe('@puppeteer/ng-schematics: test', () => { }); it('should create Node file', async () => { - const tree = await buildTestingTree('test', 'multi', { + const tree = await buildTestingTree('e2e', 'multi', { name: 'myTest', - testingFramework: 'node', + testRunner: 'node', }); expect(tree.files).not.toContain( getMultiProjectFile('e2e/tests/my-test.e2e.ts') diff --git a/packages/ng-schematics/test/src/ng-add.spec.ts b/packages/ng-schematics/test/src/ng-add.spec.ts index db5d4345934..652e96de184 100644 --- a/packages/ng-schematics/test/src/ng-add.spec.ts +++ b/packages/ng-schematics/test/src/ng-add.spec.ts @@ -5,6 +5,7 @@ import { getAngularJsonScripts, getMultiProjectFile, getPackageJson, + runSchematic, setupHttpHooks, } from './utils.js'; @@ -30,49 +31,36 @@ describe('@puppeteer/ng-schematics: ng-add', () => { }); }); it('should update create proper "ng" command for non default tester', async () => { - const tree = await buildTestingTree('ng-add', 'single', { - isDefaultTester: false, - }); + let tree = await buildTestingTree('ng-add', 'single'); + // Re-run schematic to have e2e populated + tree = await runSchematic(tree, 'ng-add'); 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, - }); + const {files} = await buildTestingTree('ng-add', 'single'); 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', + testRunner: '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'], + [`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', + testRunner: 'jest', }); const {devDependencies} = getPackageJson(tree); const {options} = getAngularJsonScripts(tree); @@ -80,32 +68,27 @@ describe('@puppeteer/ng-schematics: ng-add', () => { 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'], + [`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', + testRunner: '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'], + [`mocha`, '--config=./e2e/.mocharc.js'], ]); }); it('should create Node files', async () => { const tree = await buildTestingTree('ng-add', 'single', { - testingFramework: 'node', + testRunner: 'node', }); const {options} = getAngularJsonScripts(tree); @@ -113,25 +96,15 @@ describe('@puppeteer/ng-schematics: ng-add', () => { 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 () => { + it('should not create port value', 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); - }); }); describe('Multi projects', () => { @@ -153,33 +126,24 @@ describe('@puppeteer/ng-schematics: ng-add', () => { }); }); it('should update create proper "ng" command for non default tester', async () => { - const tree = await buildTestingTree('ng-add', 'multi', { - isDefaultTester: false, - }); + let tree = await buildTestingTree('ng-add', 'multi'); + // Re-run schematic to have e2e populated + tree = await runSchematic(tree, 'ng-add'); 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', 'multi', { - exportConfig: true, - }); - - expect(files).toContain('/.puppeteerrc.cjs'); - }); it('should not create Puppeteer config', async () => { - const {files} = await buildTestingTree('ng-add', 'multi', { - exportConfig: false, - }); + const {files} = await buildTestingTree('ng-add', 'multi'); expect(files).not.toContain(getMultiProjectFile('.puppeteerrc.cjs')); expect(files).not.toContain('/.puppeteerrc.cjs'); }); it('should create Jasmine files and update "package.json"', async () => { const tree = await buildTestingTree('ng-add', 'multi', { - testingFramework: 'jasmine', + testRunner: 'jasmine', }); const {devDependencies} = getPackageJson(tree); const {options} = getAngularJsonScripts(tree); @@ -187,21 +151,14 @@ describe('@puppeteer/ng-schematics: ng-add', () => { 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', - ], + [`jasmine`, '--config=./e2e/support/jasmine.json'], ]); }); it('should create Jest files and update "package.json"', async () => { const tree = await buildTestingTree('ng-add', 'multi', { - testingFramework: 'jest', + testRunner: 'jest', }); const {devDependencies} = getPackageJson(tree); const {options} = getAngularJsonScripts(tree); @@ -209,32 +166,27 @@ describe('@puppeteer/ng-schematics: ng-add', () => { 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'], + [`jest`, '-c', 'e2e/jest.config.js'], ]); }); it('should create Mocha files and update "package.json"', async () => { const tree = await buildTestingTree('ng-add', 'multi', { - testingFramework: 'mocha', + testRunner: 'mocha', }); const {devDependencies} = getPackageJson(tree); const {options} = getAngularJsonScripts(tree); 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'], + [`mocha`, '--config=./e2e/.mocharc.js'], ]); }); it('should create Node files', async () => { const tree = await buildTestingTree('ng-add', 'multi', { - testingFramework: 'node', + testRunner: 'node', }); const {options} = getAngularJsonScripts(tree); @@ -246,24 +198,14 @@ describe('@puppeteer/ng-schematics: ng-add', () => { 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 () => { + it('should not create port value', 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', 'multi', { - port, - }); - - const {options} = getAngularJsonScripts(tree); - expect(options['port']).toBe(port); - }); }); }); diff --git a/packages/ng-schematics/test/src/utils.ts b/packages/ng-schematics/test/src/utils.ts index 182fdc03639..8af7090317a 100644 --- a/packages/ng-schematics/test/src/utils.ts +++ b/packages/ng-schematics/test/src/utils.ts @@ -74,7 +74,7 @@ export function getMultiProjectFile(file: string): string { } export async function buildTestingTree( - command: 'ng-add' | 'test', + command: 'ng-add' | 'e2e' | 'config', type: 'single' | 'multi' = 'single', userOptions?: Record ): Promise { @@ -83,9 +83,7 @@ export async function buildTestingTree( join(__dirname, '../../lib/schematics/collection.json') ); const options = { - isDefaultTester: true, - exportConfig: false, - testingFramework: 'jasmine', + testRunner: 'jasmine', ...userOptions, }; let workingTree: UnitTestTree; @@ -121,3 +119,15 @@ export async function buildTestingTree( return await runner.runSchematic(command, options, workingTree); } + +export async function runSchematic( + tree: UnitTestTree, + command: 'ng-add' | 'test', + options?: Record +): Promise { + const runner = new SchematicTestRunner( + 'schematics', + join(__dirname, '../../lib/schematics/collection.json') + ); + return await runner.runSchematic(command, options, tree); +}