From b3c989444589e54b0f0d6164307bc0f4ab8df1a4 Mon Sep 17 00:00:00 2001 From: Vaibhav Singh Date: Tue, 23 Aug 2022 14:56:42 +0530 Subject: [PATCH] refactor: fix formatting, added prettier as dev dependency --- .github/workflows/build.yml | 3 +- .npmignore | 3 + .prettierignore | 4 +- README.md | 46 ++- package-lock.json | 24 +- package.json | 27 +- .../files/nightwatch/tsconfig.e2e.json | 8 +- src/schematics/nightwatch/index.ts | 10 +- src/schematics/nightwatch/schema.json | 12 +- .../nightwatch/utility/dependencies.ts | 41 ++- .../nightwatch/utility/json-utils.ts | 21 +- src/schematics/nightwatch/utility/jsonFile.ts | 8 +- src/schematics/nightwatch/utility/util.ts | 14 +- test/execution_spec.ts | 58 ++-- test/testDependency_spec.ts | 299 +++++++++--------- test/testUtility_spec.ts | 157 ++++----- tsconfig.json | 21 +- 17 files changed, 394 insertions(+), 362 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e7cf271..f9eee5c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,7 +10,6 @@ on: jobs: build: - runs-on: ubuntu-latest strategy: @@ -34,7 +33,7 @@ jobs: run: | npm ci npm run build - npm run test:unit + npm run test:unit - name: npm install, build, test for v10 angular app run: | npm ci diff --git a/.npmignore b/.npmignore index 05f3713..03701f0 100644 --- a/.npmignore +++ b/.npmignore @@ -2,5 +2,8 @@ *.ts !*.d.ts !src/**/files/**/*.ts +test sandbox +sandbox-v10 sandbox-v12 +sandbox-v14 diff --git a/.prettierignore b/.prettierignore index ec14872..ef3b37c 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,2 +1,4 @@ *.lock -sandbox +sandbox-v10 +sandbox-v12 +sandbox-v14 diff --git a/README.md b/README.md index 8adfe56..1beae7c 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Node CI](https://github.com/nightwatchjs/nightwatch-schematics/actions/workflows/build.yml/badge.svg?branch=main)](https://github.com/nightwatchjs/nightwatch-schematics/actions/workflows/build.yml) [![npm package](https://img.shields.io/npm/v/@nightwatch/schematics)](https://www.npmjs.com/package/@nightwatch/schematics) -> Fast and easy installation of [Nightwatch][NightwatchLink] into your projects +> Fast and easy installation of [Nightwatch][nightwatchlink] into your projects Framework & Language Supported: [Angular](#angular) @@ -11,14 +11,14 @@ Framework & Language Supported: [Angular](#angular) Nightwatch.js Schematic Logo

-This project is a Schematics implementation that allows you to easily integrate [Nightwatch][NightwatchLink] into your Angular projects. +This project is a Schematics implementation that allows you to easily integrate [Nightwatch][nightwatchlink] into your Angular projects. **This Schematic will:** 🏗️ Install Nightwatch, and it's dependencies -⚙️ Add NPM scripts for running Nightwatch tests +⚙️ Add NPM scripts for running Nightwatch tests 📦 Scaffold base Nightwatch config and test files -❓ Prompt for removal of Protractor files and configuration +❓ Prompt for removal of Protractor files and configuration ## Angular @@ -35,7 +35,7 @@ ng add @nightwatch/schematics ``` One can provide following options: -| Option | Description | +| Option | Description | |-----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | noBuilder | This will skip the builder addition, leaving the angular.json file unmodified and requiring you to run Nightwatch from the command line or through your IDE. Include --noBuilder in your ng add command. | @@ -51,8 +51,7 @@ ng run {your-project-name}:nightwatch-run These two commands do the same thing. They will run nightwatch e2e tests. -Once Nightwatch is added to your project, all [Nightwatch CLI options][NightwatchCliOptionsLink] will be available when triggering e2e tests. E.g.: `--verbose`, `--retries` etc. - +Once Nightwatch is added to your project, all [Nightwatch CLI options][nightwatchclioptionslink] will be available when triggering e2e tests. E.g.: `--verbose`, `--retries` etc. ### ✨ Demo @@ -60,13 +59,13 @@ Once Nightwatch is added to your project, all [Nightwatch CLI options][Nightwatc ### 🚀 Usage -Install [Schematics CLI][SchematicsCliLink] globally +Install [Schematics CLI][schematicsclilink] globally ```bash npm install -g @angular-devkit/schematics-cli ``` -Install [Nightwatch-schematics][NightwatchSchematicsLink] in your project +Install [Nightwatch-schematics][nightwatchschematicslink] in your project ```bash npm install @nightwatch/schematics @@ -78,7 +77,7 @@ Run following command to install Nightwatch in your project: schematics @nightwatch/schematics:ng-add ``` -Once Nightwatch is added to your project, all [Nightwatch CLI options][NightwatchCliOptionsLink] will be available when triggering e2e tests. E.g.: `--verbose`, `--retries` etc. One can update `e2e:test` to include cli options. +Once Nightwatch is added to your project, all [Nightwatch CLI options][nightwatchclioptionslink] will be available when triggering e2e tests. E.g.: `--verbose`, `--retries` etc. One can update `e2e:test` to include cli options. ## 🐛 Issues @@ -98,9 +97,9 @@ npm update @nightwatch/schematics ### Where can I ask for help and report bugs? -The best way to ask for help and to report bugs is to [open an issue][GithubIssueLink]. +The best way to ask for help and to report bugs is to [open an issue][githubissuelink]. -[Gitter][GitterLink] is another option. +[Gitter][gitterlink] is another option. ### I created new angular project, how do I remove Protractor and install Nightwatch? @@ -141,22 +140,19 @@ All you have to do is install the relevant drivers, and replace `env` value (Che } ``` - - ### How to run e2e tests using npm? | Projects | command | -|--------------------|------------------| +| ------------------ | ---------------- | | Angular App | npm run e2e | | Typescript Project | npm run e2e:test | - ## Drivers ### Drivers available to install | Name | driver | command | -|-----------------|-----------------|------------------------------------------| +| --------------- | --------------- | ---------------------------------------- | | chrome | chromedriver | `npm install chromedriver --save-dev` | | firefox | geckodriver | `npm install geckodriver --save-dev` | | selenium-server | selenium-server | `npm install selenium-server --save-dev` | @@ -214,11 +210,11 @@ npm run clean These projects: [@briebug/cypress-schematic](https://github.com/briebug/cypress-schematic/), [schuchard/prettier-schematic](https://github.com/schuchard/prettier-schematic) helped us in development of this project. Thank you! -[NightwatchLink]:https://nightwatchjs.org/ -[NightwatchCliOptionsLink]:https://nightwatchjs.org/guide/running-tests/command-line-options.html -[NightwatchGetStartedLink]:https://nightwatchjs.org/gettingstarted/ -[NightwatchSchematicsLink]:https://github.com/nightwatchjs/nightwatch-schematics -[VueNightwatchPluginLink]:https://cli.vuejs.org/core-plugins/e2e-nightwatch.html -[SchematicsCliLink]:https://www.npmjs.com/package/@angular-devkit/schematics-cli -[GithubIssueLink]:https://github.com/nightwatchjs/nightwatch-schematics/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc -[GitterLink]:https://gitter.im/nightwatchjs/nightwatch +[nightwatchlink]: https://nightwatchjs.org/ +[nightwatchclioptionslink]: https://nightwatchjs.org/guide/running-tests/command-line-options.html +[nightwatchgetstartedlink]: https://nightwatchjs.org/gettingstarted/ +[nightwatchschematicslink]: https://github.com/nightwatchjs/nightwatch-schematics +[vuenightwatchpluginlink]: https://cli.vuejs.org/core-plugins/e2e-nightwatch.html +[schematicsclilink]: https://www.npmjs.com/package/@angular-devkit/schematics-cli +[githubissuelink]: https://github.com/nightwatchjs/nightwatch-schematics/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc +[gitterlink]: https://gitter.im/nightwatchjs/nightwatch diff --git a/package-lock.json b/package-lock.json index 9703232..7e338a4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,7 +22,8 @@ "@types/node": "^18.7.6", "chai": "^4.3.6", "mocha": "^10.0.0", - "nightwatch": "^2.3.0" + "nightwatch": "^2.3.0", + "prettier": "^2.7.1" } }, "node_modules/@angular-devkit/architect": { @@ -1862,6 +1863,21 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/prettier": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -3721,6 +3737,12 @@ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "devOptional": true }, + "prettier": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", + "dev": true + }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", diff --git a/package.json b/package.json index 68883c0..2866002 100644 --- a/package.json +++ b/package.json @@ -4,34 +4,36 @@ "description": "Adds Nightwatch to an existing Angular CLI project", "scripts": { "build": "tsc -p tsconfig.json", - "build:test": "tsc -p tsconfig.spec.json", - "build:watch": "tsc -p tsconfig.json -w", - "build:test:watch": "tsc -p tsconfig.spec.json -w", "build:clean:launch:v10": "npm run build && npm run clean:launch:v10", "build:clean:launch:v12": "npm run build && npm run clean:launch:v12", "build:clean:launch:v14": "npm run build && npm run clean:launch:v14", + "build:test": "tsc -p tsconfig.spec.json", + "build:test:watch": "tsc -p tsconfig.spec.json -w", + "build:watch": "tsc -p tsconfig.json -w", + "clean": "rm -rf src/**/*.{js,js.map,d.ts} && rm -rf test/**/*.{js,js.map,d.ts}", "clean:launch:v10": "npm run clean:v10 && npm run launch:v10", "clean:launch:v12": "npm run clean:v12 && npm run launch:v12", "clean:launch:v14": "npm run clean:v14 && npm run launch:v14", "clean:v10": "git checkout HEAD -- sandbox-v10 && git clean -f -d sandbox-v10", "clean:v12": "git checkout HEAD -- sandbox-v12 && git clean -f -d sandbox-v12", "clean:v14": "git checkout HEAD -- sandbox-v14 && git clean -f -d sandbox-v14", + "dev:build": "cd sandbox && npm link ../ && ng run sandbox:nightwatch-run", + "execute": "npm run build && schematics .:ng-add", + "execute:prod": "npm run build && schematics .:ng-add --dry-run=false", + "format": "prettier --write .", "launch:v10": "npm run link:sandbox:v10 && cd sandbox-v10 && ng add $npm_package_name --remove-protractor --environment='chrome' --no-cucumber-runner && npm link ../", "launch:v12": "npm run link:sandbox:v12 && cd sandbox-v12 && ng add $npm_package_name --remove-protractor --environment='chrome' --no-cucumber-runner && npm link ../", "launch:v14": "npm run link:sandbox:v14 && cd sandbox-v14 && ng add $npm_package_name --remove-protractor --environment='chrome' --no-cucumber-runner && npm link ../", - "test:v10": "cd sandbox-v10 && ng run sandbox-v10:nightwatch-run --headless", - "test:v12": "cd sandbox-v12 && ng run sandbox-v12:nightwatch-run --headless", - "test:v14": "cd sandbox-v14 && ng run sandbox-v14:nightwatch-run --headless", "link:sandbox:v10": "npm link && cd sandbox-v10 && npm link $npm_package_name", "link:sandbox:v12": "npm link && cd sandbox-v12 && npm link $npm_package_name", "link:sandbox:v14": "npm link && cd sandbox-v14 && npm link $npm_package_name", - "unlink:sandbox": "cd sandbox && npm unlink $npm_package_name && cd .. && npm unlink", - "execute": "npm run build && schematics .:ng-add", - "execute:prod": "npm run build && schematics .:ng-add --dry-run=false", - "dev:build": "cd sandbox && npm link ../ && ng run sandbox:nightwatch-run", "test": "npm run build:clean:launch && npm run test:sandbox:v14 && npm run clean", "test:sandbox:v14": "cd sandbox-14 && npm run lint && npm run test && npm run build && npm run e2e", - "test:unit": "mocha test/**/*_spec.js" + "test:unit": "mocha test/**/*_spec.js", + "test:v10": "cd sandbox-v10 && ng run sandbox-v10:nightwatch-run --headless", + "test:v12": "cd sandbox-v12 && ng run sandbox-v12:nightwatch-run --headless", + "test:v14": "cd sandbox-v14 && ng run sandbox-v14:nightwatch-run --headless", + "unlink:sandbox": "cd sandbox && npm unlink $npm_package_name && cd .. && npm unlink" }, "keywords": [ "schematics", @@ -72,6 +74,7 @@ "@types/node": "^18.7.6", "chai": "^4.3.6", "mocha": "^10.0.0", - "nightwatch": "^2.3.0" + "nightwatch": "^2.3.0", + "prettier": "^2.7.1" } } diff --git a/src/schematics/nightwatch/files/nightwatch/tsconfig.e2e.json b/src/schematics/nightwatch/files/nightwatch/tsconfig.e2e.json index f28bba5..e9c6c19 100644 --- a/src/schematics/nightwatch/files/nightwatch/tsconfig.e2e.json +++ b/src/schematics/nightwatch/files/nightwatch/tsconfig.e2e.json @@ -3,11 +3,7 @@ "outDir": "../out-tsc/nightwatch", "module": "commonjs", "target": "es5", - "types": [ - "node" - ], + "types": ["node"] }, - "include": [ - "src/**/*" - ] + "include": ["src/**/*"] } diff --git a/src/schematics/nightwatch/index.ts b/src/schematics/nightwatch/index.ts index 7cfc43e..de32ee3 100644 --- a/src/schematics/nightwatch/index.ts +++ b/src/schematics/nightwatch/index.ts @@ -16,11 +16,7 @@ import { map, concatMap } from 'rxjs/operators'; import { Observable, of, concat } from 'rxjs'; import { NodeDependencyType } from './enums'; import { NodePackage, SchematicsOptions, ScriptHash } from './interfaces'; -import { - addPropertyToPackageJson, - getAngularVersion, - getLatestNodeVersion, -} from './utility/util'; +import { addPropertyToPackageJson, getAngularVersion, getLatestNodeVersion } from './utility/util'; import { addPackageJsonDependency, removePackageJsonDependency } from './utility/dependencies'; import getFramework from './utility/framework'; import { normalize, strings } from '@angular-devkit/core'; @@ -33,7 +29,7 @@ export default function (_options: SchematicsOptions): Rule { return (tree: Tree, _context: SchematicContext) => { _options = { ..._options, __version__: getAngularVersion(tree) }; - if(_options.__version__ === 0) { + if (_options.__version__ === 0) { throw new SchematicsException('Angular project not found'); } @@ -126,7 +122,7 @@ function updateDependencies(options: SchematicsOptions): Rule { removePackageJsonDependency(tree, { type: NodeDependencyType.Dev, - name: packageName + name: packageName, }); return tree; diff --git a/src/schematics/nightwatch/schema.json b/src/schematics/nightwatch/schema.json index a72ed3d..a6659af 100644 --- a/src/schematics/nightwatch/schema.json +++ b/src/schematics/nightwatch/schema.json @@ -28,12 +28,7 @@ "environment": { "description": "The browser you want to run your e2e tests", "type": "string", - "enum": [ - "chrome", - "firefox", - "safari", - "selenium" - ], + "enum": ["chrome", "firefox", "safari", "selenium"], "$default": { "$source": "argv", "index": 2 @@ -46,8 +41,5 @@ "type": "boolean" } }, - "required": [ - "environment", - "cucumberRunner" - ] + "required": ["environment", "cucumberRunner"] } diff --git a/src/schematics/nightwatch/utility/dependencies.ts b/src/schematics/nightwatch/utility/dependencies.ts index 1d504b6..31062ef 100644 --- a/src/schematics/nightwatch/utility/dependencies.ts +++ b/src/schematics/nightwatch/utility/dependencies.ts @@ -19,7 +19,7 @@ export function getPackageJsonDependency(tree: Tree, name: string): NodeDependen } const depsNode = packageJson.get([depType]); if (depsNode?.type === 'object') { - const depNode = findNodeAtLocation(depsNode, [name]) + const depNode = findNodeAtLocation(depsNode, [name]); if (depNode && depNode.type === 'string') { const version = depNode.value; dep = { @@ -41,9 +41,14 @@ export function addPackageJsonDependency(tree: Tree, dependency: NodeDependency) if (!depsNode) { // Haven't found the dependencies key, add it to the root of the package.json. - insertPropertyInAstObjectInOrder(recorder, packageJsonAst.JsonAst, dependency.type, {[dependency.name]: dependency.version}, 2); - - } else if ( depsNode && depsNode.type === 'object') { + insertPropertyInAstObjectInOrder( + recorder, + packageJsonAst.JsonAst, + dependency.type, + { [dependency.name]: dependency.version }, + 2 + ); + } else if (depsNode && depsNode.type === 'object') { // check if package already added const depNode = findNodeAtLocation(depsNode, [dependency.name]); @@ -52,12 +57,15 @@ export function addPackageJsonDependency(tree: Tree, dependency: NodeDependency) insertPropertyInAstObjectInOrder(recorder, depsNode, dependency.name, dependency.version, 4); } else if (dependency.overwrite) { // Package found, update version if overwrite. - if(depNode.colonOffset === undefined) { + if (depNode.colonOffset === undefined) { throw new Error('Invalid package.json. Was expecting an object'); - } - - recorder.remove(depNode.offset + depNode.colonOffset, depNode.offset + depNode.length ); - recorder.insertRight(depNode.offset + depNode.colonOffset, JSON.stringify(dependency.version)); + } + + recorder.remove(depNode.offset + depNode.colonOffset, depNode.offset + depNode.length); + recorder.insertRight( + depNode.offset + depNode.colonOffset, + JSON.stringify(dependency.version) + ); } } @@ -71,24 +79,25 @@ export function removePackageJsonDependency(tree: Tree, dependency: DeleteNodeDe if (!depsNode || !depsNode.children) { return; - } + } const depNode = findNodeAtLocation(depsNode, [dependency.name])?.parent; if (!depNode) return; - - let start = depNode.offset, length = depNode.length; - + + let start = depNode.offset, + length = depNode.length; + let pos = depsNode.children.indexOf(depNode); // Previous property present - if (pos -1 > -1) { + if (pos - 1 > -1) { const prevNode = depsNode.children[pos - 1]; start = prevNode.offset + prevNode.length + 1; length = depNode.offset + depNode.length - start; } - + // Next property present if (pos < depsNode.children.length - 1) { - length ++; // remove comma + length++; // remove comma } recorder.remove(start, length); diff --git a/src/schematics/nightwatch/utility/json-utils.ts b/src/schematics/nightwatch/utility/json-utils.ts index 585b520..79206fc 100644 --- a/src/schematics/nightwatch/utility/json-utils.ts +++ b/src/schematics/nightwatch/utility/json-utils.ts @@ -2,7 +2,6 @@ import { JsonValue } from '@angular-devkit/core'; import { UpdateRecorder } from '@angular-devkit/schematics'; import { Node } from 'jsonc-parser'; - function _buildIndent(count: number): string { return '\n' + new Array(count + 1).join(' '); } @@ -23,7 +22,7 @@ export function appendPropertyInAstObject( if (node.parent) { recorder.insertRight( - node.offset + node.length, + node.offset + node.length, indentStr + `"${propertyName}": ${JSON.stringify(value, null, 2).replace(/\n/g, indentStr)}` + indentStr.slice(0, -2) @@ -41,7 +40,7 @@ export function insertPropertyInAstObjectInOrder( indent: number ) { if (node.children === undefined) { - throw new Error(`Failed to insert JSON property ${propertyName}`) + throw new Error(`Failed to insert JSON property ${propertyName}`); } //Find insertion info. @@ -50,7 +49,7 @@ export function insertPropertyInAstObjectInOrder( let isLastProp = false; const last = node.children[node.children.length - 1]; for (const prop of node.children) { - if(prop.children === undefined) continue; + if (prop.children === undefined) continue; if (prop.children[0].value > propertyName) { if (prev) { @@ -74,12 +73,12 @@ export function insertPropertyInAstObjectInOrder( const indentStr = _buildIndent(indent); const insertIndex = - insertAfterProp === null ? node.offset + 1 : insertAfterProp.offset + insertAfterProp.length + 1; + insertAfterProp === null + ? node.offset + 1 + : insertAfterProp.offset + insertAfterProp.length + 1; - const insertString = `${indentStr}"${propertyName}": ${JSON.stringify(value, null, 2).replace(/\n/g, indentStr)}` + - (node.children && node.children.length > 0? ',' : '\n' ); - recorder.insertRight( - insertIndex, - insertString - ); + const insertString = + `${indentStr}"${propertyName}": ${JSON.stringify(value, null, 2).replace(/\n/g, indentStr)}` + + (node.children && node.children.length > 0 ? ',' : '\n'); + recorder.insertRight(insertIndex, insertString); } diff --git a/src/schematics/nightwatch/utility/jsonFile.ts b/src/schematics/nightwatch/utility/jsonFile.ts index 19c2226..b64bc3c 100644 --- a/src/schematics/nightwatch/utility/jsonFile.ts +++ b/src/schematics/nightwatch/utility/jsonFile.ts @@ -29,7 +29,7 @@ export class JSONFile { } private _jsonAst: Node | undefined; - public get JsonAst(): Node { + public get JsonAst(): Node { if (this._jsonAst) { return this._jsonAst; } @@ -46,15 +46,15 @@ export class JSONFile { )} at location: ${offset}.` ); } - + if (this._jsonAst === undefined) { throw new Error(`Failed to parse "${this.path}" as JSON AST Object.`); } - + return this._jsonAst; } - get(jsonPath: JSONPath): Node |undefined { + get(jsonPath: JSONPath): Node | undefined { if (!this.JsonAst) { return undefined; } diff --git a/src/schematics/nightwatch/utility/util.ts b/src/schematics/nightwatch/utility/util.ts index 43aa011..a00c348 100644 --- a/src/schematics/nightwatch/utility/util.ts +++ b/src/schematics/nightwatch/utility/util.ts @@ -4,9 +4,7 @@ import { findNodeAtLocation } from 'jsonc-parser'; import { Config, pkgJson } from '../enums'; import { NodePackage } from '../interfaces'; import { getPackageJsonDependency } from './dependencies'; -import { - insertPropertyInAstObjectInOrder, -} from './json-utils'; +import { insertPropertyInAstObjectInOrder } from './json-utils'; import { JSONFile } from './jsonFile'; export function getAngularVersion(tree: Tree): number { @@ -34,8 +32,13 @@ export function addPropertyToPackageJson( if (!pkgNode) { // outer node missing, add key/value - insertPropertyInAstObjectInOrder(recorder, packageJsonAst.JsonAst, propertyName, propertyValue, Config.JsonIndentLevel); - + insertPropertyInAstObjectInOrder( + recorder, + packageJsonAst.JsonAst, + propertyName, + propertyValue, + Config.JsonIndentLevel + ); } else if (pkgNode.type === 'object') { // property exists, update values for (let [key, value] of Object.entries(propertyValue)) { @@ -50,7 +53,6 @@ export function addPropertyToPackageJson( // script found, overwrite value context.logger.debug(`overwriting ${key} with ${value}`); - recorder.remove(innerNode.offset, innerNode.length); recorder.insertRight(innerNode.offset, JSON.stringify(value)); } diff --git a/test/execution_spec.ts b/test/execution_spec.ts index cbb858f..d63b583 100644 --- a/test/execution_spec.ts +++ b/test/execution_spec.ts @@ -1,12 +1,12 @@ import { Tree } from '@angular-devkit/schematics'; import { SchematicTestRunner } from '@angular-devkit/schematics/testing'; -import { expect } from "chai"; +import { expect } from 'chai'; import * as path from 'path'; const NUMBER_OF_SCAFFOLDED_FILES = 27; const collectionPath = path.join(__dirname, '../src/schematics/collection.json'); -describe('@nightwatch/schematics', async function() { +describe('@nightwatch/schematics', async function () { async function getWorkspaceTree(appName = 'sandbox') { const ngRunner = new SchematicTestRunner('@schematics/angular', ''); @@ -32,7 +32,7 @@ describe('@nightwatch/schematics', async function() { const runner: SchematicTestRunner = new SchematicTestRunner('schematics', collectionPath); - it('Should throw if environment argument is missing', async function() { + it('Should throw if environment argument is missing', async function () { let errorMessage: any; try { await runner.runSchematicAsync('ng-add', {}, Tree.empty()).toPromise(); @@ -42,26 +42,40 @@ describe('@nightwatch/schematics', async function() { expect(errorMessage).to.match(/required property 'environment'/); }); - it('should throw error if cucumberRunner argument is missing', async function() { + it('should throw error if cucumberRunner argument is missing', async function () { let errorMessage: any; try { - await runner.runSchematicAsync('ng-add', {environment: 'chrome'}, await getWorkspaceTree()).toPromise(); + await runner + .runSchematicAsync('ng-add', { environment: 'chrome' }, await getWorkspaceTree()) + .toPromise(); } catch (error) { errorMessage = error.message; } expect(errorMessage).to.match(/required property 'cucumberRunner'/); - }) + }); - it('should add nightwatch config, and test cucumber as test runner is present in the nightwatch config', - async function() { - runner.runSchematicAsync('ng-add', { environment: 'chrome', cucumberRunner: true }, await getWorkspaceTree()).toPromise().then((tree) => { - expect(tree.readContent('/projects/sandbox/nightwatch.conf.js')).to.match(/[a-zA-Z]+: 'cucumber'/) - }) - }) + it('should add nightwatch config, and test cucumber as test runner is present in the nightwatch config', async function () { + runner + .runSchematicAsync( + 'ng-add', + { environment: 'chrome', cucumberRunner: true }, + await getWorkspaceTree() + ) + .toPromise() + .then((tree) => { + expect(tree.readContent('/projects/sandbox/nightwatch.conf.js')).to.match( + /[a-zA-Z]+: 'cucumber'/ + ); + }); + }); - it('should add nightwatch config, and tests in workspace', async function() { + it('should add nightwatch config, and tests in workspace', async function () { runner - .runSchematicAsync('ng-add', { environment: 'chrome', cucumberRunner: false }, await getWorkspaceTree()) + .runSchematicAsync( + 'ng-add', + { environment: 'chrome', cucumberRunner: false }, + await getWorkspaceTree() + ) .toPromise() .then((tree) => { expect(tree.exists('/nightwatch/tsconfig.e2e.json')).to.be.true; @@ -70,9 +84,13 @@ describe('@nightwatch/schematics', async function() { }); }); - it('should overwrite angular.json to include `nightwatch-run`', async function() { + it('should overwrite angular.json to include `nightwatch-run`', async function () { runner - .runSchematicAsync('ng-add', { environment: 'chrome', cucumberRunner: false }, await getWorkspaceTree()) + .runSchematicAsync( + 'ng-add', + { environment: 'chrome', cucumberRunner: false }, + await getWorkspaceTree() + ) .toPromise() .then((tree) => { expect(tree.readContent('/angular.json')).to.contain( @@ -94,9 +112,13 @@ describe('@nightwatch/schematics', async function() { }); }); - it('should add nightwatch in angular', async function() { + it('should add nightwatch in angular', async function () { runner - .runSchematicAsync('ng-add', { environment: 'chrome', cucumberRunner: false }, await getWorkspaceTree()) + .runSchematicAsync( + 'ng-add', + { environment: 'chrome', cucumberRunner: false }, + await getWorkspaceTree() + ) .toPromise() .then((tree) => { expect(tree.files.length).to.equal(NUMBER_OF_SCAFFOLDED_FILES); diff --git a/test/testDependency_spec.ts b/test/testDependency_spec.ts index a0cfe5f..359e822 100644 --- a/test/testDependency_spec.ts +++ b/test/testDependency_spec.ts @@ -1,16 +1,18 @@ -import {getPackageJsonDependency, addPackageJsonDependency, removePackageJsonDependency} from '../src/schematics/nightwatch/utility/dependencies'; -import {expect} from 'chai' +import { + getPackageJsonDependency, + addPackageJsonDependency, + removePackageJsonDependency, +} from '../src/schematics/nightwatch/utility/dependencies'; +import { expect } from 'chai'; import { NodeDependencyType } from '../src/schematics/nightwatch/enums'; import { UnitTestTree } from '@angular-devkit/schematics/testing'; import { HostTree } from '@angular-devkit/schematics'; import { virtualFs } from '@angular-devkit/core'; -describe('test dependency manipulation functions', function() { - - it('should be able get package dependency', function() { - - let host = new virtualFs.test.TestHost({ - '/package.json': `{ +describe('test dependency manipulation functions', function () { + it('should be able get package dependency', function () { + let host = new virtualFs.test.TestHost({ + '/package.json': `{ "name": "test", "dependencies": { "@angular/common": "^6.0.0" @@ -20,36 +22,35 @@ describe('test dependency manipulation functions', function() { "typescript": "~4.2.3" } }`, - }); - - let tree = new UnitTestTree(new HostTree(host)); - - const dependency = { - type: 'dependencies', - name: '@angular/common', - version: '^6.0.0' - }; - - const result = getPackageJsonDependency(tree, dependency.name); - expect(result).to.deep.equal(dependency); - - const devDependencie = { - type: 'devDependencies', - name: 'typescript', - version: '~4.2.3' - } - - const result2 = getPackageJsonDependency(tree, devDependencie.name); - expect(result2).to.deep.equal(devDependencie); - - const notFound = getPackageJsonDependency(tree, 'notFound'); - expect(notFound).to.be.null; }); - it('should be able to append package dependency', async function() { + let tree = new UnitTestTree(new HostTree(host)); + + const dependency = { + type: 'dependencies', + name: '@angular/common', + version: '^6.0.0', + }; + + const result = getPackageJsonDependency(tree, dependency.name); + expect(result).to.deep.equal(dependency); + + const devDependencie = { + type: 'devDependencies', + name: 'typescript', + version: '~4.2.3', + }; + + const result2 = getPackageJsonDependency(tree, devDependencie.name); + expect(result2).to.deep.equal(devDependencie); + + const notFound = getPackageJsonDependency(tree, 'notFound'); + expect(notFound).to.be.null; + }); - let host = new virtualFs.test.TestHost({ - '/package.json': ` + it('should be able to append package dependency', async function () { + let host = new virtualFs.test.TestHost({ + '/package.json': ` { "name": "test", "dependencies": { @@ -57,25 +58,24 @@ describe('test dependency manipulation functions', function() { } } `, - }); - - let tree = new UnitTestTree(new HostTree(host)); - - const dependency = { - type: NodeDependencyType.Default, - name: '@angular/core', - version: '^6.0.0' - }; - - addPackageJsonDependency(tree, dependency); - const result = getPackageJsonDependency(tree, dependency.name); - expect(result).to.deep.equal(dependency); }); - it('should be able to add dev dependency to empty ', async function() { + let tree = new UnitTestTree(new HostTree(host)); - let host = new virtualFs.test.TestHost({ - '/package.json': ` + const dependency = { + type: NodeDependencyType.Default, + name: '@angular/core', + version: '^6.0.0', + }; + + addPackageJsonDependency(tree, dependency); + const result = getPackageJsonDependency(tree, dependency.name); + expect(result).to.deep.equal(dependency); + }); + + it('should be able to add dev dependency to empty ', async function () { + let host = new virtualFs.test.TestHost({ + '/package.json': ` { "name": "test", "dependencies": { @@ -83,30 +83,28 @@ describe('test dependency manipulation functions', function() { } } `, - }); - - let tree = new UnitTestTree(new HostTree(host)); - - const dependency = { - type: NodeDependencyType.Dev, - name: '@angular/core', - version: '^6.0.0' - }; - - addPackageJsonDependency(tree, dependency); - const result = getPackageJsonDependency(tree, dependency.name); - expect(result).to.deep.equal(dependency); - - - - const dependency2 = { - type: NodeDependencyType.Dev, - name: '@angular/cli', - version: '^6.0.0' - }; - - host = new virtualFs.test.TestHost({ - '/package.json': ` + }); + + let tree = new UnitTestTree(new HostTree(host)); + + const dependency = { + type: NodeDependencyType.Dev, + name: '@angular/core', + version: '^6.0.0', + }; + + addPackageJsonDependency(tree, dependency); + const result = getPackageJsonDependency(tree, dependency.name); + expect(result).to.deep.equal(dependency); + + const dependency2 = { + type: NodeDependencyType.Dev, + name: '@angular/cli', + version: '^6.0.0', + }; + + host = new virtualFs.test.TestHost({ + '/package.json': ` { "name": "test", "dependencies": { @@ -114,38 +112,35 @@ describe('test dependency manipulation functions', function() { }, "devDependencies": {} }`, - }); - - - tree = new UnitTestTree(new HostTree(host)); + }); + tree = new UnitTestTree(new HostTree(host)); - addPackageJsonDependency(tree, dependency); - addPackageJsonDependency(tree, dependency2); - const result2 = getPackageJsonDependency(tree, dependency.name); - expect(result2).to.deep.equal(dependency); + addPackageJsonDependency(tree, dependency); + addPackageJsonDependency(tree, dependency2); + const result2 = getPackageJsonDependency(tree, dependency.name); + expect(result2).to.deep.equal(dependency); - const result3 = getPackageJsonDependency(tree, dependency2.name); - expect(result3).to.deep.equal(dependency2); + const result3 = getPackageJsonDependency(tree, dependency2.name); + expect(result3).to.deep.equal(dependency2); - host = new virtualFs.test.TestHost({ - '/package.json': ` + host = new virtualFs.test.TestHost({ + '/package.json': ` { }`, - }); - - tree = new UnitTestTree(new HostTree(host)); - - - addPackageJsonDependency(tree, dependency); - const result4 = getPackageJsonDependency(tree, dependency.name); - expect(result4).to.deep.equal(dependency); }); - it('should be able to remove dependencies', function() { - let host = new virtualFs.test.TestHost({ - '/package.json': ` + tree = new UnitTestTree(new HostTree(host)); + + addPackageJsonDependency(tree, dependency); + const result4 = getPackageJsonDependency(tree, dependency.name); + expect(result4).to.deep.equal(dependency); + }); + + it('should be able to remove dependencies', function () { + let host = new virtualFs.test.TestHost({ + '/package.json': ` { "name": "test", "dependencies": { @@ -154,28 +149,28 @@ describe('test dependency manipulation functions', function() { } } `, - }); - - let tree = new UnitTestTree(new HostTree(host)); - - const dependency = { - type: NodeDependencyType.Default, - name: '@angular/core', - version: '^6.0.0' - }; - - removePackageJsonDependency(tree, dependency); - const result = getPackageJsonDependency(tree, dependency.name); - expect(result).to.be.null; - - addPackageJsonDependency(tree, dependency); - const result2 = getPackageJsonDependency(tree, dependency.name); - expect(result2).to.deep.equal(dependency); }); - it('should be able to remove multiple dependencies', function() { - let host = new virtualFs.test.TestHost({ - '/package.json': `{ + let tree = new UnitTestTree(new HostTree(host)); + + const dependency = { + type: NodeDependencyType.Default, + name: '@angular/core', + version: '^6.0.0', + }; + + removePackageJsonDependency(tree, dependency); + const result = getPackageJsonDependency(tree, dependency.name); + expect(result).to.be.null; + + addPackageJsonDependency(tree, dependency); + const result2 = getPackageJsonDependency(tree, dependency.name); + expect(result2).to.deep.equal(dependency); + }); + + it('should be able to remove multiple dependencies', function () { + let host = new virtualFs.test.TestHost({ + '/package.json': `{ "name": "sandbox-v10", "version": "0.0.0", "scripts": { @@ -206,39 +201,37 @@ describe('test dependency manipulation functions', function() { "@angular/compiler-cli": "~10.0.9" } }`, - }); - - - const dependency = { - type: NodeDependencyType.Default, - name: '@angular/core', - version: '~10.0.9' - }; - - const dependency1 = { - type: NodeDependencyType.Default, - name: '@angular/compiler', - version: '~10.0.9' - }; - - const dependency2 = { - type: NodeDependencyType.Default, - name: '@angular/animations', - version: '~10.0.9' - }; - - let tree = new UnitTestTree(new HostTree(host)); - removePackageJsonDependency(tree, dependency); - const result = getPackageJsonDependency(tree, dependency.name); - expect(result).to.be.null; - - removePackageJsonDependency(tree, dependency1); - const result1 = getPackageJsonDependency(tree, dependency1.name); - expect(result1).to.be.null; - - removePackageJsonDependency(tree, dependency2); - const result2 = getPackageJsonDependency(tree, dependency2.name); - expect(result2).to.be.null; - }); -}); \ No newline at end of file + + const dependency = { + type: NodeDependencyType.Default, + name: '@angular/core', + version: '~10.0.9', + }; + + const dependency1 = { + type: NodeDependencyType.Default, + name: '@angular/compiler', + version: '~10.0.9', + }; + + const dependency2 = { + type: NodeDependencyType.Default, + name: '@angular/animations', + version: '~10.0.9', + }; + + let tree = new UnitTestTree(new HostTree(host)); + removePackageJsonDependency(tree, dependency); + const result = getPackageJsonDependency(tree, dependency.name); + expect(result).to.be.null; + + removePackageJsonDependency(tree, dependency1); + const result1 = getPackageJsonDependency(tree, dependency1.name); + expect(result1).to.be.null; + + removePackageJsonDependency(tree, dependency2); + const result2 = getPackageJsonDependency(tree, dependency2.name); + expect(result2).to.be.null; + }); +}); diff --git a/test/testUtility_spec.ts b/test/testUtility_spec.ts index f6be302..9e81fb5 100644 --- a/test/testUtility_spec.ts +++ b/test/testUtility_spec.ts @@ -1,59 +1,67 @@ -import { JsonObject, virtualFs } from "@angular-devkit/core"; -import { Logger, LoggerApi, LogLevel } from "@angular-devkit/core/src/logger"; -import { Engine, HostTree, MergeStrategy, Schematic, SchematicContext, TaskConfigurationGenerator, TaskId } from "@angular-devkit/schematics"; -import { UnitTestTree } from "@angular-devkit/schematics/testing"; -import { addPropertyToPackageJson } from "../src/schematics/nightwatch/utility/util"; +import { JsonObject, virtualFs } from '@angular-devkit/core'; +import { Logger, LoggerApi, LogLevel } from '@angular-devkit/core/src/logger'; +import { + Engine, + HostTree, + MergeStrategy, + Schematic, + SchematicContext, + TaskConfigurationGenerator, + TaskId, +} from '@angular-devkit/schematics'; +import { UnitTestTree } from '@angular-devkit/schematics/testing'; +import { addPropertyToPackageJson } from '../src/schematics/nightwatch/utility/util'; import { findNodeAtLocation } from 'jsonc-parser'; -import { JSONFile } from "../src/schematics/nightwatch/utility/jsonFile"; -import { expect } from "chai"; - +import { JSONFile } from '../src/schematics/nightwatch/utility/jsonFile'; +import { expect } from 'chai'; class MockLogger implements LoggerApi { - createChild(_name: string): Logger { - throw new Error("Method not implemented."); - } - log(_level: LogLevel, message: string, _metadata?: JsonObject | undefined): void { - console.log(message); - } - debug(_message: string, _metadata?: JsonObject | undefined): void { - console.debug(_message); - } - info(_message: string, _metadata?: JsonObject | undefined): void { - throw new Error("Method not implemented."); - } - warn(_message: string, _metadata?: JsonObject | undefined): void { - throw new Error("Method not implemented."); - } - error(_message: string, _metadata?: JsonObject | undefined): void { - throw new Error("Method not implemented."); - } - fatal(_message: string, _metadata?: JsonObject | undefined): void { - throw new Error("Method not implemented."); - } + createChild(_name: string): Logger { + throw new Error('Method not implemented.'); + } + log(_level: LogLevel, message: string, _metadata?: JsonObject | undefined): void { + console.log(message); + } + debug(_message: string, _metadata?: JsonObject | undefined): void { + console.debug(_message); + } + info(_message: string, _metadata?: JsonObject | undefined): void { + throw new Error('Method not implemented.'); + } + warn(_message: string, _metadata?: JsonObject | undefined): void { + throw new Error('Method not implemented.'); + } + error(_message: string, _metadata?: JsonObject | undefined): void { + throw new Error('Method not implemented.'); + } + fatal(_message: string, _metadata?: JsonObject | undefined): void { + throw new Error('Method not implemented.'); + } } class MockContext implements SchematicContext { - debug: boolean; - engine: Engine<{}, {}>; - logger: MockLogger; - schematic: Schematic<{}, {}>; - strategy: MergeStrategy; - interactive: boolean; - addTask(_task: TaskConfigurationGenerator, _dependencies?: TaskId[] | undefined): TaskId { - throw new Error("Method not implemented."); - } - - constructor(){ - this.logger = new MockLogger(); - } + debug: boolean; + engine: Engine<{}, {}>; + logger: MockLogger; + schematic: Schematic<{}, {}>; + strategy: MergeStrategy; + interactive: boolean; + addTask( + _task: TaskConfigurationGenerator, + _dependencies?: TaskId[] | undefined + ): TaskId { + throw new Error('Method not implemented.'); + } + + constructor() { + this.logger = new MockLogger(); + } } - -describe('test utility functions', function() { - - it('should add entries to package.json', function(){ - let host = new virtualFs.test.TestHost({ - '/package.json': ` +describe('test utility functions', function () { + it('should add entries to package.json', function () { + let host = new virtualFs.test.TestHost({ + '/package.json': ` { "name": "test", "dependencies": { @@ -64,30 +72,31 @@ describe('test utility functions', function() { "typescript": "~4.2.3" } }`, - }); + }); - let tree = new UnitTestTree(new HostTree(host)); - + let tree = new UnitTestTree(new HostTree(host)); - const scriptsToAdd = { - 'e2e:test': `./node_modules/.bin/nightwatch --env 'firefox' --config './nightwatch.conf.js'` - } + const scriptsToAdd = { + 'e2e:test': `./node_modules/.bin/nightwatch --env 'firefox' --config './nightwatch.conf.js'`, + }; - addPropertyToPackageJson(tree, new MockContext(), 'scripts', scriptsToAdd); + addPropertyToPackageJson(tree, new MockContext(), 'scripts', scriptsToAdd); - const packageJson = new JSONFile(tree, '/package.json'); - const result = findNodeAtLocation(packageJson.JsonAst, ['scripts']); - expect(result).not.to.be.undefined; - - if (result != undefined) { - const result2 = findNodeAtLocation( result, ['e2e:test']); - expect(result2?.value).to.equal(`./node_modules/.bin/nightwatch --env 'firefox' --config './nightwatch.conf.js'`); - } - }); + const packageJson = new JSONFile(tree, '/package.json'); + const result = findNodeAtLocation(packageJson.JsonAst, ['scripts']); + expect(result).not.to.be.undefined; - it('should add entries to existing properties', async function() { - let host = new virtualFs.test.TestHost({ - '/package.json': `{ + if (result != undefined) { + const result2 = findNodeAtLocation(result, ['e2e:test']); + expect(result2?.value).to.equal( + `./node_modules/.bin/nightwatch --env 'firefox' --config './nightwatch.conf.js'` + ); + } + }); + + it('should add entries to existing properties', async function () { + let host = new virtualFs.test.TestHost({ + '/package.json': `{ "name": "sandbox-v10", "version": "0.0.0", "scripts": { @@ -117,18 +126,20 @@ describe('test utility functions', function() { let tree = new UnitTestTree(new HostTree(host)); const scriptsToAdd = { - 'e2e:test': `./node_modules/.bin/nightwatch --env 'firefox' --config './nightwatch.conf.js'` - } + 'e2e:test': `./node_modules/.bin/nightwatch --env 'firefox' --config './nightwatch.conf.js'`, + }; addPropertyToPackageJson(tree, new MockContext(), 'scripts', scriptsToAdd); const packageJson = new JSONFile(tree, '/package.json'); const result = findNodeAtLocation(packageJson.JsonAst, ['scripts']); expect(result).not.to.be.undefined; - + if (result != undefined) { - const result2 = findNodeAtLocation( result, ['e2e:test']); - expect(result2?.value).to.equal(`./node_modules/.bin/nightwatch --env 'firefox' --config './nightwatch.conf.js'`); + const result2 = findNodeAtLocation(result, ['e2e:test']); + expect(result2?.value).to.equal( + `./node_modules/.bin/nightwatch --env 'firefox' --config './nightwatch.conf.js'` + ); } }); -}); \ No newline at end of file +}); diff --git a/tsconfig.json b/tsconfig.json index 6bb122c..ee3d05c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,10 +1,7 @@ { "compilerOptions": { "baseUrl": "tsconfig", - "lib": [ - "es2018", - "dom" - ], + "lib": ["es2018", "dom"], "declaration": true, "module": "commonjs", "moduleResolution": "node", @@ -20,18 +17,8 @@ "sourceMap": true, "strictNullChecks": true, "target": "es6", - "types": [ - "node", - "mocha", - "chai" - ] + "types": ["node", "mocha", "chai"] }, - "include": [ - "src/**/*", - "test/**/*" - ], - "exclude": [ - "src/*/files/**/*", - "src/**/*_spec.ts", - ] + "include": ["src/**/*", "test/**/*"], + "exclude": ["src/*/files/**/*", "src/**/*_spec.ts"] }