diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 240caa909..e9dcd1b37 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -130,23 +130,23 @@ applicable: own generator. Alternatively, if the additional behaviour is only small, you could also consider adding this as a optional part of the init schema). -**_Cypress Example:_** +**_Playwright Example:_** -**@ensono-stacks/cypress:init** - Add a cypress testing framework to an +**@ensono-stacks/playwright:init** - Add a Playwright testing framework to an application and configures everything surrounding the test execution and reporting -**@ensono-stacks/cypress:init-deployment** - Adds e2e tests as a stage within +**@ensono-stacks/playwright:init-deployment** - Adds e2e tests as a stage within pipeline execution and reporting to azure -**@ensono-stacks/cypress:accessibility** - Adds accessibility tests and it's +**@ensono-stacks/playwright:accessibility** - Adds accessibility tests and it's dependencies/configuration to the application/project ### Development process From a process perspective, it is recommended to develop your desired end state first, which can then be reverse engineered back into a plugin/generators. Here -is an example of the process followed for creating our `@ensono-stacks/cypress` +is an example of the process followed for creating our `@ensono-stacks/playwright` plugin: **_Step 1: Creating your end state_** @@ -154,17 +154,17 @@ plugin: - Create a baseline workspace with a Next.js application. Commit this to your `main` branch -- Create a new branch, e.g. `cypress-baseline` for the _init_ generator. In - this branch, install and configure the Cypress testing framework with the +- Create a new branch, e.g. `playwright-baseline` for the _init_ generator. In + this branch, install and configure the Playwright testing framework with the required configurations. -- Create a new branch from `cypress-baseline` for the _init-deployment_ - generator (`cypress-deployment`), adding the additional requirements for - deploying your application with cypress tests. +- Create a new branch from `playwright-baseline` for the _init-deployment_ + generator (`playwright-deployment`), adding the additional requirements for + deploying your application with Playwright tests. -- Create a new branch from `cypress-baseline` for the _accessibility_ - generator (`cypress-accessibility`), adding the additional requirements for - adding accessibility tests using cypress to your application. +- Create a new branch from `playwright-baseline` for the _accessibility_ + generator (`playwright-accessibility`), adding the additional requirements for + adding accessibility tests using Playwright to your application. **_Step 2: Create your plugin, generators and unit tests._** @@ -189,17 +189,17 @@ nx generate @nx/plugin:generator --project= ``` - _init_ generator: Use Git to review the differences between the - `cypress-baseline` branch and the `main` branch. This will help identify the + `playwright-baseline` branch and the `main` branch. This will help identify the files your generator needs to manipulate or create, then write all of the unit tests to check that the desired end state is met. - _init-deployment_ generator: Use Git to review the differences between the - `cypress-deployment` branch and the `cypress-baseline` branch. This will + `playwright-deployment` branch and the `playwright-baseline` branch. This will help identify files which need to be amended/created on top of the _init_ files and create your unit tests. - _accessibility_ generator: Use Git to review the differences between the - `cypress-accessibility` branch and the `cypress-baseline` branch. Again + `playwright-accessibility` branch and the `playwright-baseline` branch. Again creating the relevant unit tests. **_Step 3: Implementation_** diff --git a/README.md b/README.md index e72defa18..97ff4d746 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ projects, we have several stacks plugins available! | Plugin | Description | | :------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [`@ensono-stacks/create-stacks-workspace`](https://stacks.ensono.com/docs/getting_started/create-stacks-workspace/ensono-stacks-create-stacks-workspace) | Create an Nx workspace using stacks!
  • Create an Nx workspace for a Next application with your choice of testing framework!
  • Create a testing project for the generated Next application. Supported: Playwright & Cypress
  • | +| [`@ensono-stacks/create-stacks-workspace`](https://stacks.ensono.com/docs/getting_started/create-stacks-workspace/ensono-stacks-create-stacks-workspace) | Create an Nx workspace using stacks!
  • Create an Nx workspace for a Next application with your choice of testing framework!
  • Create a testing project for the generated Next application. Supported: Playwright
  • | | [`@ensono-stacks/workspace`](https://stacks.ensono.com/docs/getting_started/workspace/ensono-stacks-workspace) | 'Stackify' your existing Nx workspace
  • Add build and deploy infrastructure to your workspace
  • Set up libraries to manage code & commit quality
  • | | [`@ensono-stacks/next`](https://stacks.ensono.com/docs/getting_started/next/ensono-stacks-next) | Enhance your Next.js project with Stacks!
  • Add stacks configuration and developer tools to an existing next application
  • Add NextAuth.js to your next application
  • Add build and deploy infrastructure to your next application
  • | | [`@ensono-stacks/azure-node`](https://stacks.ensono.com/docs/getting_started/azure-node/ensono-stacks-azure-node) |
  • Add Azure app insights to a node project in your stacks workspace
  • | diff --git a/e2e/create-e2e/project.json b/e2e/create-e2e/project.json index 74b7f30f5..1e31eeabc 100644 --- a/e2e/create-e2e/project.json +++ b/e2e/create-e2e/project.json @@ -8,7 +8,6 @@ "create", "workspace", "next", - "cypress", "playwright" ], "targets": { diff --git a/e2e/create-e2e/tests/create.spec.ts b/e2e/create-e2e/tests/create.spec.ts index a2a2a1d79..a771e0a08 100644 --- a/e2e/create-e2e/tests/create.spec.ts +++ b/e2e/create-e2e/tests/create.spec.ts @@ -215,24 +215,6 @@ describe('create', () => { expect(() => run()).not.toThrow(); }); - it('can install with cypress set as e2eTestRunner', async () => { - const run = () => - execSync( - `npx --yes @ensono-stacks/create-stacks-workspace@latest proj --nxVersion=${nxVersion} --business.company=Ensono --business.domain=Stacks --business.component=Nx --cloud.platform=azure --cloud.region=euw --domain.internal=nonprod.amidostacks.com --domain.external=prod.amidostacks.com --terraform.group=tf-group --terraform.storage=tf-storage --terraform.container=tf-container --vcs.type=github --preset=next --appName=test-app --e2eTestRunner=cypress --nxCloud=skip --skipGit --no-interactive --verbose`, - { - cwd: temporaryDirectory, - stdio: 'inherit', - env: { - ...process.env, - npm_config_cache: cacheDirectory, - HUSKY: '0', - }, - }, - ); - - expect(() => run()).not.toThrow(); - }); - it('can install different nx version', async () => { const run = () => execSync( diff --git a/e2e/cypress-e2e/jest.config.ts b/e2e/cypress-e2e/jest.config.ts deleted file mode 100644 index 8ca366813..000000000 --- a/e2e/cypress-e2e/jest.config.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* eslint-disable */ -export default { - displayName: 'cypress-e2e', - preset: '../../jest.preset.js', - globals: {}, - transform: { - '^.+\\.[tj]s$': [ - 'ts-jest', - { - tsconfig: '/tsconfig.spec.json', - }, - ], - }, - moduleFileExtensions: ['ts', 'js', 'html'], - coverageDirectory: '../../coverage/e2e/cypress-e2e', -}; \ No newline at end of file diff --git a/e2e/cypress-e2e/project.json b/e2e/cypress-e2e/project.json deleted file mode 100644 index 6ad34ce79..000000000 --- a/e2e/cypress-e2e/project.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "cypress-e2e", - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "projectType": "application", - "sourceRoot": "e2e/cypress-e2e/src", - "tags": ["e2e"], - "implicitDependencies": ["cypress", "next", "workspace", "create"], - "targets": { - "e2e": { - "executor": "@ensono-stacks/e2e:e2e", - "options": { - "verdaccioConfig": ".verdaccio/config.yml", - "jestOptions": { - "jestConfig": "e2e/cypress-e2e/jest.config.ts", - "passWithNoTests": true - } - } - } - } -} diff --git a/e2e/cypress-e2e/tests/cypress.spec.ts b/e2e/cypress-e2e/tests/cypress.spec.ts deleted file mode 100644 index b2a958450..000000000 --- a/e2e/cypress-e2e/tests/cypress.spec.ts +++ /dev/null @@ -1,146 +0,0 @@ -import { newProject, runTarget, targetOptions } from '@ensono-stacks/e2e'; -import { - checkFilesExist, - readJson, - runNxCommand, - runNxCommandAsync, - uniq, -} from '@nx/plugin/testing'; - -import { - CYPRESS_VERSION, - CYPRESSMULTIREPORTERS_VERSION, - MOCHAWESOME_VERSION, - MOCHAWESOMEJUNITREPORTER_VERSION, - MOCHAWESOMEMERGE_VERSION, - AXECORE_VERSION, - CYPRESSAXE_VERSION, -} from '../../../packages/cypress/src/versions'; - -let baseProject, applicationDirectory, cypressDirectory; -describe('cypress e2e', () => { - jest.setTimeout(1_000_000); - - function setupBaseProject() { - baseProject = uniq('cypress'); - applicationDirectory = `apps/${baseProject}`; - cypressDirectory = `${applicationDirectory}-e2e`; - runNxCommand( - `generate @nx/next:application ${baseProject} --directory=apps/${baseProject} --e2eTestRunner=none --style=none --appDir=false --src=true --projectNameAndRootFormat=as-provided --verbose`, - ); - return { baseProject, applicationDirectory, cypressDirectory }; - } - - beforeAll(async () => { - await newProject(['@ensono-stacks/cypress'], ['@nx/next']); - }); - - afterAll(async () => { - await runNxCommandAsync('reset'); - }); - - describe('--project', () => { - it('errors when the project does not exist', async () => { - const project = uniq('imaginaryProjectThatDoesNotExist'); - await runNxCommandAsync( - `generate @ensono-stacks/cypress:init ${project}`, - ).catch(stderr => expect(stderr?.code).toEqual(1)); - }); - - describe('should successfully run and amend config files if project does exist', () => { - beforeAll(async () => { - setupBaseProject(); - await runNxCommandAsync( - `generate @ensono-stacks/cypress:init --project=${baseProject} --no-interactive --verbose`, - ); - }); - - it('should add/update the relevant files', () => { - expect(() => - checkFilesExist( - `${cypressDirectory}/cypress.config.ts`, - `${cypressDirectory}/project.json`, - `${cypressDirectory}/src/e2e/app.cy.ts`, - `${cypressDirectory}/src/support/e2e.ts`, - `${cypressDirectory}/tsconfig.json`, - ), - ).not.toThrow(); - }); - - it('should update the package.json', () => { - const packageJson = readJson('package.json'); - expect(packageJson?.devDependencies).toMatchObject({ - cypress: CYPRESS_VERSION, - 'cypress-multi-reporters': CYPRESSMULTIREPORTERS_VERSION, - mochawesome: MOCHAWESOME_VERSION, - 'mochawesome-merge': MOCHAWESOMEMERGE_VERSION, - 'mocha-junit-reporter': MOCHAWESOMEJUNITREPORTER_VERSION, - }); - }); - - describe('should be a runnable test suite', () => { - - let results; - beforeAll(async () => { - process.env.CI = 'true'; - results = - await runTarget( - `${baseProject}-e2e`, - targetOptions.e2e, - undefined, - '--env.grep="should be up and running"', - ); - }); - - it('should run the e2e tests', () => { - expect(results).toContain( - `Successfully ran target e2e for project ${baseProject}`, - ); - }); - - - describe('should run executor to produce html reports', () => { - beforeAll(async () => { - results = - await runTarget( - `${baseProject}-e2e`, - targetOptions['html-report'], - undefined, - '--configuration=ci' - ); - }); - - it('should produce html and json reports as output', () => { - expect(results).toContain(`Successfully ran target html-report for project ${baseProject}`); - expect(() => - checkFilesExist( - `test-results/${baseProject}-e2e/downloads/mochawesome-report/merged-html-report.html`, - `test-results/${baseProject}-e2e/downloads/merged-html-report.json`, - ), - ).not.toThrow(); - }); - }); - }); - - it('should successfully add accessibility test files and add dependencies', async () => { - runNxCommand( - `generate @ensono-stacks/cypress:accessibility --project=${baseProject} --no-interactive`, - ); - - expect(() => - checkFilesExist( - `${cypressDirectory}/src/e2e/axe-accessibility.cy.ts`, - ), - ).not.toThrow(); - - // add axe packages to package.json - const packageJson = readJson('package.json'); - expect(packageJson?.devDependencies).toMatchObject({ - 'axe-core': AXECORE_VERSION, - 'cypress-axe': CYPRESSAXE_VERSION, - }); - }); - - }); - }); -}); \ No newline at end of file diff --git a/e2e/cypress-e2e/tsconfig.json b/e2e/cypress-e2e/tsconfig.json deleted file mode 100644 index 862691da7..000000000 --- a/e2e/cypress-e2e/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.spec.json" - } - ] -} diff --git a/e2e/cypress-e2e/tsconfig.spec.json b/e2e/cypress-e2e/tsconfig.spec.json deleted file mode 100644 index 5591a03c7..000000000 --- a/e2e/cypress-e2e/tsconfig.spec.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../dist/out-tsc", - "module": "commonjs", - "types": ["jest", "node"] - }, - "include": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts", "**/*.d.ts"] -} diff --git a/migrations.json b/migrations.json index 3f0fc964a..91ccfbec0 100644 --- a/migrations.json +++ b/migrations.json @@ -119,22 +119,6 @@ "package": "@nx/jest", "name": "move-options-to-target-defaults" }, - { - "cli": "nx", - "version": "16.8.0-beta.4", - "description": "Update to Cypress v13. Most noteable change is video recording is off by default. This migration will only update if the workspace is already on Cypress v12. https://docs.cypress.io/guides/references/migration-guide#Migrating-to-Cypress-130", - "implementation": "./src/migrations/update-16-8-0/cypress-13", - "package": "@nx/cypress", - "name": "update-16-8-0-cypress-13" - }, - { - "cli": "nx", - "version": "18.1.0-beta.3", - "description": "Update to Cypress ^13.6.6 if the workspace is using Cypress v13 to ensure workspaces don't use v13.6.5 which has an issue when verifying Cypress.", - "implementation": "./src/migrations/update-18-1-0/update-cypress-version-13-6-6", - "package": "@nx/cypress", - "name": "update-cypress-version-13-6-6" - }, { "cli": "nx", "version": "17.2.7", diff --git a/package-lock.json b/package-lock.json index 67d3cd8e7..4b00e3b25 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,7 +30,6 @@ "@commitlint/config-nx-scopes": "19.3.0", "@commitlint/cz-commitlint": "19.2.0", "@jscutlery/semver": "^5.2.2", - "@nx/cypress": "18.3.5", "@nx/devkit": "18.3.5", "@nx/eslint": "18.3.5", "@nx/eslint-plugin": "18.3.5", @@ -4810,15 +4809,6 @@ "node": ">= 8" } }, - "node_modules/@nrwl/cypress": { - "version": "18.3.5", - "resolved": "https://registry.npmjs.org/@nrwl/cypress/-/cypress-18.3.5.tgz", - "integrity": "sha512-so2D+WJQGXBIg37FhDpdqYuiSPHOOWrwUwsq6wrVNfzYAUkejHK4J+n5Kw6056ZdKI/yJ3niw50eNprb7yKFpg==", - "dev": true, - "dependencies": { - "@nx/cypress": "18.3.5" - } - }, "node_modules/@nrwl/devkit": { "version": "18.3.5", "resolved": "https://registry.npmjs.org/@nrwl/devkit/-/devkit-18.3.5.tgz", @@ -4922,30 +4912,6 @@ "@nx/workspace": "18.3.5" } }, - "node_modules/@nx/cypress": { - "version": "18.3.5", - "resolved": "https://registry.npmjs.org/@nx/cypress/-/cypress-18.3.5.tgz", - "integrity": "sha512-02wB/tuctBHO3IyOs4F1wMHc566BWcC4Trj4x9BAXj1fI8WI9GF1/tNF0Yzwf1pe9QKqmSFp9zg07+tus++eQg==", - "dev": true, - "dependencies": { - "@nrwl/cypress": "18.3.5", - "@nx/devkit": "18.3.5", - "@nx/eslint": "18.3.5", - "@nx/js": "18.3.5", - "@phenomnomnominal/tsquery": "~5.0.1", - "detect-port": "^1.5.1", - "semver": "^7.5.3", - "tslib": "^2.3.0" - }, - "peerDependencies": { - "cypress": ">= 3 < 14" - }, - "peerDependenciesMeta": { - "cypress": { - "optional": true - } - } - }, "node_modules/@nx/devkit": { "version": "18.3.5", "resolved": "https://registry.npmjs.org/@nx/devkit/-/devkit-18.3.5.tgz", diff --git a/package.json b/package.json index 2cde489a3..82ab91249 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,6 @@ "@commitlint/config-nx-scopes": "19.3.0", "@commitlint/cz-commitlint": "19.2.0", "@jscutlery/semver": "^5.2.2", - "@nx/cypress": "18.3.5", "@nx/devkit": "18.3.5", "@nx/eslint": "18.3.5", "@nx/eslint-plugin": "18.3.5", diff --git a/packages/common/local-publish/src/executors/local-publish/executor.ts b/packages/common/local-publish/src/executors/local-publish/executor.ts index 24fcd51ce..d197c329c 100644 --- a/packages/common/local-publish/src/executors/local-publish/executor.ts +++ b/packages/common/local-publish/src/executors/local-publish/executor.ts @@ -10,7 +10,6 @@ const packageDirectories = { 'azure-react': 'packages/azure-react', 'common-core': 'packages/common/core', create: 'packages/create', - cypress: 'packages/cypress', logger: 'packages/logger', next: 'packages/next', playwright: 'packages/playwright', @@ -23,7 +22,6 @@ const packageNames = { '@ensono-stacks/azure-react': 'azure-react', '@ensono-stacks/core': 'common-core', '@ensono-stacks/create-stacks-workspace': 'create', - '@ensono-stacks/cypress': 'cypress', '@ensono-stacks/logger': 'logger', '@ensono-stacks/next': 'next', '@ensono-stacks/playwright': 'playwright', diff --git a/packages/create/bin/create-stacks-workspace.spec.ts b/packages/create/bin/create-stacks-workspace.spec.ts index a52c8f50f..1333b6edd 100644 --- a/packages/create/bin/create-stacks-workspace.spec.ts +++ b/packages/create/bin/create-stacks-workspace.spec.ts @@ -166,10 +166,10 @@ describe('determine app-name', () => { describe('determine e2e test runner', () => { it('with valid test runner', async () => { const result = await determineE2eTestRunner({ - e2eTestRunner: 'cypress', + e2eTestRunner: 'playwright', } as yargs.Arguments); - expect(result).toBe('cypress'); + expect(result).toBe('playwright'); }); it('with no test runner', async () => { @@ -190,7 +190,7 @@ describe('determine e2e test runner', () => { } as yargs.Arguments); expect(consoleErrorSpy).toHaveBeenCalledWith( - chalk.red`Invalid test runner: It must be one of the following:none,playwright,cypress`, + chalk.red`Invalid test runner: It must be one of the following:none,playwright`, ); expect(mockExit).toHaveBeenCalledWith(1); }); @@ -213,7 +213,7 @@ describe('get configuration', () => { await getConfiguration({ _: ['myrepo'], preset: 'apps', - e2eTestRunner: 'cypress', + e2eTestRunner: 'playwright', } as yargs.Arguments); }); }); diff --git a/packages/create/bin/create-stacks-workspace.ts b/packages/create/bin/create-stacks-workspace.ts index 0436bf60d..ce2c6d1af 100644 --- a/packages/create/bin/create-stacks-workspace.ts +++ b/packages/create/bin/create-stacks-workspace.ts @@ -48,10 +48,6 @@ const e2eTestRunnerOptions: { name: E2eTestRunner; message: string }[] = [ name: E2eTestRunner.Playwright, message: 'playwright', }, - { - name: E2eTestRunner.Cypress, - message: 'cypress', - }, ]; export async function determineRepoName( diff --git a/packages/create/bin/dependencies.spec.ts b/packages/create/bin/dependencies.spec.ts index 7308c73a6..f1d8ce82b 100644 --- a/packages/create/bin/dependencies.spec.ts +++ b/packages/create/bin/dependencies.spec.ts @@ -75,26 +75,6 @@ describe('workspace generator', () => { ); }); - it('runs generators correctly with cypress test runner', async () => { - const generators = getGeneratorsToRun({ - e2eTestRunner: E2eTestRunner.Cypress, - appName: 'cypress-app', - } as yargs.Arguments); - await runGenerators(generators, 'folder/path'); - - expect(execAsync).toBeCalledTimes(2); - expect(execAsync).toHaveBeenNthCalledWith( - 1, - 'npx nx g @ensono-stacks/workspace:init', - 'folder/path', - ); - expect(execAsync).toHaveBeenNthCalledWith( - 2, - 'npx nx g @ensono-stacks/cypress:init --project=cypress-app', - 'folder/path', - ); - }); - it('runs generators correctly with playwright test runner', async () => { const generators = getGeneratorsToRun({ e2eTestRunner: E2eTestRunner.Playwright, diff --git a/packages/create/bin/dependencies.ts b/packages/create/bin/dependencies.ts index 617683627..275fa73a5 100644 --- a/packages/create/bin/dependencies.ts +++ b/packages/create/bin/dependencies.ts @@ -24,10 +24,9 @@ export function normaliseForwardedArgv( updatedForwardArgv['preset'] = forwardArgv['preset'] === 'next' ? 'apps' : forwardArgv['preset']; - // As we have our own playwright and cypress implementations, we pass in none for the initial Nx create workspace to avoid potential conflict/errors etc. + // As we have our own playwright implementation, we pass in none for the initial Nx create workspace to avoid potential conflict/errors etc. updatedForwardArgv['e2eTestRunner'] = - updatedForwardArgv['e2eTestRunner'] === 'playwright' || - updatedForwardArgv['e2eTestRunner'] === 'cypress' + updatedForwardArgv['e2eTestRunner'] === 'playwright' ? 'none' : updatedForwardArgv['e2eTestRunner']; return updatedForwardArgv; diff --git a/packages/create/bin/types.ts b/packages/create/bin/types.ts index 3e2f613b1..50bfe4578 100644 --- a/packages/create/bin/types.ts +++ b/packages/create/bin/types.ts @@ -48,5 +48,4 @@ export enum Preset { export enum E2eTestRunner { None = 'none', Playwright = 'playwright', - Cypress = 'cypress', } diff --git a/packages/create/project.json b/packages/create/project.json index 57ea7f43a..f209f4370 100644 --- a/packages/create/project.json +++ b/packages/create/project.json @@ -4,7 +4,7 @@ "sourceRoot": "packages/create/src", "projectType": "library", "tags": ["plugin"], - "implicitDependencies": ["workspace", "playwright", "cypress"], + "implicitDependencies": ["workspace", "playwright"], "targets": { "build": { diff --git a/packages/cypress/.eslintrc.json b/packages/cypress/.eslintrc.json deleted file mode 100644 index d7df7033c..000000000 --- a/packages/cypress/.eslintrc.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "extends": ["../../.eslintrc.json"], - "ignorePatterns": ["!**/*"], - "overrides": [ - { - "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], - "excludedFiles": ["./src/generators/**/files/**"], - "parserOptions": { - "project": ["packages/cypress/tsconfig.*?.json"] - } - }, - { - "files": ["*.ts", "*.tsx"], - "rules": {} - }, - { - "files": ["*.js", "*.jsx"], - "rules": {} - }, - { - "files": [ - "./package.json", - "./generators.json", - "./executors.json" - ], - "parser": "jsonc-eslint-parser", - "rules": { - "@nx/nx-plugin-checks": "error", - "@nx/dependency-checks": "error" - } - } - ] -} diff --git a/packages/cypress/README.md b/packages/cypress/README.md deleted file mode 100644 index 3e437e077..000000000 --- a/packages/cypress/README.md +++ /dev/null @@ -1,48 +0,0 @@ -# @ensono-stacks/cypress -## Deprecated: This plugin is no longer supported. Ensono-stacks/cypress 2.0.7 is the final release version and may not be compatible with the ensono-stacks/workspace plugin above version 2.0.7. - -Please visit the stacks documentation page for `cypress` -[here](https://stacks.ensono.com/docs/getting_started/cypress/ensono-stacks-cypress) -for more information - -## Generators and Executors - -View a list of the plugin executors/generators through the following command: - -```bash -nx list @ensono-stacks/cypress -``` - -## Development - -### Building - -Run the following command to build the plugin - -```bash -nx build cypress -``` - -### Tests - -Run the following to execute the unit tests via [jest](https://jestjs.io/). - -```bash -nx test cypress -``` - -### Linting - -Run the following to lint the code using [ESLint](https://eslint.org/). - -```bash -nx lint cypress -``` - -### Publish - -Run the following to publish the NPM package - -```bash -nx publish cypress -``` diff --git a/packages/cypress/executors.json b/packages/cypress/executors.json deleted file mode 100644 index 4e495eca1..000000000 --- a/packages/cypress/executors.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "$schema": "http://json-schema.org/schema", - "executors": {} -} diff --git a/packages/cypress/generators.json b/packages/cypress/generators.json deleted file mode 100644 index e697561b3..000000000 --- a/packages/cypress/generators.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "$schema": "http://json-schema.org/schema", - "name": "cypress", - "version": "0.0.1", - "generators": { - "init": { - "factory": "./src/generators/init/generator", - "schema": "./src/generators/init/schema.json", - "description": "init generator" - }, - "init-deployment": { - "factory": "./src/generators/init-deployment/generator", - "schema": "./src/generators/init-deployment/schema.json", - "description": "The deployment generator contains all the pipeline and infrastructure change for cypress." - }, - "accessibility": { - "factory": "./src/generators/accessibility/generator", - "schema": "./src/generators/accessibility/schema.json", - "description": "accessibility generator" - } - // "visual-regression": { - // "factory": "./src/generators/visual-regression/generator", - // "schema": "./src/generators/visual-regression/schema.json", - // "description": "visual regression generator" - // }, - // "visual-regression-deployment": { - // "factory": "./src/generators/visual-regression-deployment/generator", - // "schema": "./src/generators/visual-regression-deployment/schema.json", - // "description": "visual-regression-deployment generator" - // } - } -} diff --git a/packages/cypress/jest.config.ts b/packages/cypress/jest.config.ts deleted file mode 100644 index 4083f1d34..000000000 --- a/packages/cypress/jest.config.ts +++ /dev/null @@ -1,16 +0,0 @@ -export default { - displayName: 'cypress', - preset: '../../jest.preset.js', - globals: {}, - testEnvironment: 'node', - transform: { - '^.+\\.[tj]s$': [ - 'ts-jest', - { - tsconfig: '/tsconfig.spec.json', - }, - ], - }, - moduleFileExtensions: ['ts', 'js', 'html'], - coverageDirectory: '../../coverage/packages/cypress', -}; diff --git a/packages/cypress/package.json b/packages/cypress/package.json deleted file mode 100644 index 57881c9a4..000000000 --- a/packages/cypress/package.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "@ensono-stacks/cypress", - "version": "2.0.6", - "main": "src/index.js", - "generators": "./generators.json", - "executors": "./executors.json", - "repository": { - "type": "git", - "url": "https://github.com/ensono/stacks-nx-plugins.git" - }, - "peerDependencies": { - "@nx/devkit": "^18.3.5", - "@nx/eslint": "^18.3.5", - "ts-morph": "^23.0.0", - "tslib": "^2.7.0" - }, - "dependencies": { - "@ensono-stacks/core": "2.0.7", - "@nx/cypress": "^18.3.5", - "@nx/js": "^18.3.5", - "yaml": "^2.5.0" - } -} diff --git a/packages/cypress/project.json b/packages/cypress/project.json deleted file mode 100644 index 9a9a46555..000000000 --- a/packages/cypress/project.json +++ /dev/null @@ -1,137 +0,0 @@ -{ - "name": "cypress", - "$schema": "../../node_modules/nx/schemas/project-schema.json", - "sourceRoot": "packages/cypress/src", - "projectType": "library", - "tags": ["plugin"], - "targets": { - "build": { - "executor": "@nx/js:tsc", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/packages/cypress", - "main": "packages/cypress/src/index.ts", - "tsConfig": "packages/cypress/tsconfig.lib.json", - "assets": [ - "packages/cypress/*.md", - { - "input": "./packages/cypress/src", - "glob": "**/!(*.ts)", - "output": "./src" - }, - { - "input": "./packages/cypress/src", - "glob": "**/*.d.ts", - "output": "./src" - }, - { - "input": "./packages/cypress", - "glob": "generators.json", - "output": "." - }, - { - "input": "./packages/cypress", - "glob": "executors.json", - "output": "." - } - ] - } - }, - "lint": { - "executor": "@nx/eslint:lint", - "outputs": ["{options.outputFile}"], - "options": { - "lintFilePatterns": [ - "packages/cypress/**/*.ts", - "packages/cypress/generators.json", - "packages/cypress/executors.json", - "packages/cypress/package.json" - ] - }, - "configurations": { - "release": { - "fix": true - } - } - }, - "test": { - "executor": "@nx/jest:jest", - "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], - "options": { - "jestConfig": "packages/cypress/jest.config.ts" - } - }, - "dependency": { - "executor": "nx:run-commands", - "options": { - "commands": [ - "nx run cypress:lint:release", - "git add packages/cypress/package.json", - "git commit --no-verify --amend --no-edit", - "git push --no-verify --atomic origin main {tag}" - ], - "parallel": false, - "forwardAllArgs": false - } - }, - "version": { - "executor": "@jscutlery/semver:version", - "options": { - "trackDeps": true, - "dryRun": false, - "skipRootChangelog": true, - "skipProjectChangelog": true, - "noVerify": true, - "push": false, - "skipCommit": true, - "commitMessageFormat": "chore({projectName}): release version ${version} [skip ci]" - }, - "configurations": { - "prerelease": { - "releaseAs": "prerelease", - "preid": "alpha", - "postTargets": [ - "cypress:lint:release", - "cypress:build", - "cypress:publish:prerelease" - ] - }, - "release": { - "skipCommit": false, - "postTargets": [ - "cypress:dependency", - "cypress:build", - "cypress:publish", - "cypress:github" - ] - }, - "local-release": { - "postTargets": [ - "cypress:lint:release", - "cypress:build", - "create:publish" - ], - "allowEmptyRelease": true - } - } - }, - "publish": { - "executor": "ngx-deploy-npm:deploy", - "options": { - "access": "public" - }, - "configurations": { - "prerelease": { - "tag": "dev" - } - } - }, - "github": { - "executor": "@jscutlery/semver:github", - "options": { - "tag": "${tag}", - "notes": "${notes}" - } - } - } -} diff --git a/packages/cypress/src/generators/accessibility/__snapshots__/generator.spec.ts.snap b/packages/cypress/src/generators/accessibility/__snapshots__/generator.spec.ts.snap deleted file mode 100644 index 295300af1..000000000 --- a/packages/cypress/src/generators/accessibility/__snapshots__/generator.spec.ts.snap +++ /dev/null @@ -1,77 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`cypress accessibility generator should correctly add accessibility should update the applications cypress.config.ts 1`] = ` -"import { nxE2EPreset } from '@nx/cypress/plugins/cypress-preset'; - -import { defineConfig } from 'cypress'; - -const appName = process.env.NX_TASK_TARGET_PROJECT as string; -const outputFolderForProject = process.env.CI - ? \`../../test-results/\${appName}\` - : 'test-results'; - -export default defineConfig({ - e2e: { - ...nxE2EPreset(__filename, { cypressDir: 'src' }), - setupNodeEvents(on, config) { - on('task', { - log(message) { - console.log(message); - return null; - }, - table(message) { - console.table(message); - return null; - }, - }); - }, - }, - reporter: '../../node_modules/cypress-multi-reporters', - reporterOptions: { - reporterEnabled: !process.env.CI - ? 'spec' - : 'spec, mocha-junit-reporter, mochawesome', - mochaJunitReporterReporterOptions: { - mochaFile: outputFolderForProject.concat( - \`/downloads/junit-report/results-\${appName}-[hash].xml\` - ), - }, - mochawesomeReporterOptions: { - charts: true, - overwrite: false, - html: false, - json: true, - reportDir: outputFolderForProject.concat('/downloads/reports-json-file'), - reportFilename: '[name].html', - embeddedScreenshots: true, - inlineAssets: true, - }, - }, -}); -" -`; - -exports[`cypress accessibility generator should correctly update the setUpNodeEvents if it already exists 1`] = ` -"export default defineConfig({ - ...baseConfig, - e2e: { - setupNodeEvents(on, config) { - on('before:browser:launch', (file) => { - //do something - }); - - on('task', { - log(message) { - console.log(message); - return null; - }, - table(message) { - console.table(message); - return null; - }, - }); - }, - }, -}); -" -`; diff --git a/packages/cypress/src/generators/accessibility/files/src/e2e/axe-accessibility.cy.ts__template__ b/packages/cypress/src/generators/accessibility/files/src/e2e/axe-accessibility.cy.ts__template__ deleted file mode 100644 index 561318d31..000000000 --- a/packages/cypress/src/generators/accessibility/files/src/e2e/axe-accessibility.cy.ts__template__ +++ /dev/null @@ -1,59 +0,0 @@ -import 'cypress-axe'; -import { terminalLogAxe } from '../support/e2e'; -// Basic usage - -describe('@accessibility-tests', () => { - beforeEach(() => { - cy.visit('/'); - cy.injectAxe(); - }); - - it('Has no detectable a11y violations on load (with custom parameters)', () => { - // Test the page at initial load (with context and options) - cy.checkA11y( - undefined, - { - runOnly: { - type: 'tag', - values: ['wcag2a'], - }, - }, - terminalLogAxe - ); - }); - - it('Has no detectable a11y violations on load (filtering to only include critical impact violations)', () => { - // Test on initial load, only report and assert for critical impact items - cy.checkA11y( - undefined, - { - includedImpacts: ['critical'], - }, - terminalLogAxe - ); - }); - - // Basic usage after interacting with the page - it('Has no a11y violations after button click', () => { - // Interact with the page, then check for a11y issues - cy.contains('a', "What's next?").click(); - cy.checkA11y(undefined, undefined, terminalLogAxe); - }); - - it('Only logs a11y violations while allowing the test to pass', () => { - // Do not fail the test when there are accessibility failures - cy.checkA11y(undefined, undefined, terminalLogAxe, true); - }); - - it('Has no a11y violations after asynchronous load', () => { - // Retry the check if there are initial failures - cy.checkA11y( - undefined, - { - retries: 3, - interval: 100, - }, - terminalLogAxe - ); - }); -}); diff --git a/packages/cypress/src/generators/accessibility/generator.spec.ts b/packages/cypress/src/generators/accessibility/generator.spec.ts deleted file mode 100644 index 6925f6e34..000000000 --- a/packages/cypress/src/generators/accessibility/generator.spec.ts +++ /dev/null @@ -1,214 +0,0 @@ -import { tsMorphTree } from '@ensono-stacks/core'; -import { createNextApp } from '@ensono-stacks/test'; -import { joinPathFragments, readJson, Tree } from '@nx/devkit'; -import * as fs from 'fs'; -import path from 'path'; - -import generator from './generator'; -import { AccessibilityGeneratorSchema } from './schema'; -import { terminalLogAxeBody } from './utils/update-files'; -import { checkOneOccurence } from '../../utils/test-utils'; -import { AXECORE_VERSION, CYPRESSAXE_VERSION } from '../../versions'; -import initGenerator from '../init/generator'; - -const applicationName = 'application'; -const applicationDirectory = `apps/${applicationName}`; -const E2EApplicationDirectory = `apps/${applicationName}-e2e`; - -jest.mock('@nx/devkit', () => { - const actual = jest.requireActual('@nx/devkit'); - - return { - ...actual, - getProjects: jest.fn( - () => - new Map([ - [ - applicationName, - { - root: applicationDirectory, - sourceRoot: applicationDirectory, - name: applicationName, - }, - ], - ]), - ), - }; -}); - -function compareToFile(fileInTree, fileToMatchAgainstPath: string) { - const expectedFileContents = fs - .readFileSync(path.resolve(__dirname, fileToMatchAgainstPath), 'utf8') - .replaceAll(/(\r)/gm, '') - .trim(); - const fileContents = fileInTree.getFullText().trim(); - expect(fileContents).toBe(expectedFileContents); -} - -describe('cypress accessibility generator', () => { - let appTree: Tree; - let options: AccessibilityGeneratorSchema; - let project; - beforeEach(async () => { - options = { - project: applicationName, - }; - appTree = await createNextApp(options.project); - project = tsMorphTree(appTree); - }); - - it('should raise an error if a cypress app has not yet been added', async () => { - await generator(appTree, options).catch(error => { - expect(error.message).toEqual( - 'The dependent CypressInit generator has not been executed', - ); - }); - }); - - it('should raise an error if an invalid project is specified', async () => { - await generator(appTree, { project: 'nosuchproject' }).catch(error => { - expect(error.message).toEqual('nosuchproject does not exist.'); - }); - }); - - it('should correctly update the setUpNodeEvents if it already exists', async () => { - await initGenerator(appTree, options); - const config = project.addSourceFileAtPath( - joinPathFragments(E2EApplicationDirectory, 'cypress.config.ts'), - ); - config.replaceWithText(`export default defineConfig({ - ...baseConfig, - e2e: { - setupNodeEvents(on, config) { - on('before:browser:launch', (file) => { - //do something - }); - }, - }, - });`); - config.saveSync(); - await generator(appTree, options); - expect( - appTree - .read( - joinPathFragments( - E2EApplicationDirectory, - 'cypress.config.ts', - ), - ) - .toString(), - ).toMatchSnapshot(); - }); - - describe('should correctly add accessibility', () => { - beforeEach(async () => { - await initGenerator(appTree, options); - await generator(appTree, options); - }); - - it('should update nx.json and tag executed generator true', async () => { - const nxJson = readJson(appTree, 'nx.json'); - - expect( - nxJson.stacks.executedGenerators.project[ - options.project - ].includes('CypressAccessibility'), - ).toBe(true); - }); - - it('should throw an error if the generator has ran before', async () => { - const gen = await generator(appTree, { - ...options, - }); - expect(gen).toBe(false); - }); - - it('should run successfully and create the accessibility test', async () => { - // axe-accessibility.spec.ts to be added - const filePath = joinPathFragments( - E2EApplicationDirectory, - 'src', - 'e2e', - 'axe-accessibility.cy.ts', - ); - expect(appTree.exists(filePath)).toBeTruthy(); - compareToFile( - project.addSourceFileAtPath(filePath), - './files/src/e2e/axe-accessibility.cy.ts__template__', - ); - }); - - it('should update the package.json with the required dependencies', () => { - // expect package.json updated - const packageJson = JSON.parse( - appTree.read('/package.json', 'utf8'), - ); - expect(packageJson?.devDependencies).toMatchObject({ - 'axe-core': AXECORE_VERSION, - 'cypress-axe': CYPRESSAXE_VERSION, - }); - }); - - it('should update the applications cypress.config.ts', () => { - expect( - appTree - .read( - joinPathFragments( - E2EApplicationDirectory, - 'cypress.config.ts', - ), - ) - .toString(), - ).toMatchSnapshot(); - }); - - it('should update the applications e2e.ts support file', () => { - const filePath = joinPathFragments( - E2EApplicationDirectory, - 'src', - 'support', - 'e2e.ts', - ); - const file = project.addSourceFileAtPath(filePath); - const expectedFunction = file.getFunction('terminalLogAxe'); - const parameters = expectedFunction.getParameters(); - expect(parameters.length).toEqual(1); - const violationsParameter = expectedFunction - .getParameters() - .find(parameter => parameter.getName() === 'violations'); - const parameterType = violationsParameter.getType().getText(); - expect(parameterType).toBe('Result[]'); - expect(expectedFunction?.getBodyText()).toBe(terminalLogAxeBody); - const importExists = file - .getImportDeclarations() - .some( - importDecl => - importDecl.getModuleSpecifierValue() === 'axe-core' && - importDecl - .getNamedImports() - .some( - namedImport => - namedImport.getName() === 'Result', - ), - ); - expect(importExists).toBe(true); - }); - - it('should update the applications cypress tsconfig.json file', () => { - const tsconfig = readJson( - appTree, - joinPathFragments( - E2EApplicationDirectory, - 'src', - 'tsconfig.json', - ), - ); - expect( - checkOneOccurence( - tsconfig.compilerOptions.types, - 'cypress-axe', - ), - ).toBeTruthy(); - }); - }); -}); diff --git a/packages/cypress/src/generators/accessibility/generator.ts b/packages/cypress/src/generators/accessibility/generator.ts deleted file mode 100644 index 286928b64..000000000 --- a/packages/cypress/src/generators/accessibility/generator.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { - hasGeneratorExecutedForProject, - isGeneratorInExecutedListForProject, - verifyPluginCanBeInstalled, -} from '@ensono-stacks/core'; -import { - addDependenciesToPackageJson, - formatFiles, - Tree, - updateJson, - joinPathFragments, -} from '@nx/devkit'; - -import { AccessibilityGeneratorSchema } from './schema'; -import { addTerminalLogging, updateCypressConfig } from './utils/update-files'; -import { normalizeOptions, addFiles } from '../../utils/test-utils'; -import { AXECORE_VERSION, CYPRESSAXE_VERSION } from '../../versions'; - -async function updateDependencies(tree: Tree) { - return addDependenciesToPackageJson( - tree, - {}, - { - 'axe-core': AXECORE_VERSION, - 'cypress-axe': CYPRESSAXE_VERSION, - }, - ); -} - -function updateTsConfig(tree: Tree, project: string) { - updateJson( - tree, - joinPathFragments(project, 'src', 'tsconfig.json'), - tsConfigJson => { - const updatedProjectJson = { ...tsConfigJson }; - if ( - !updatedProjectJson.compilerOptions.types.includes( - 'cypress-axe', - ) - ) { - updatedProjectJson.compilerOptions.types.push('cypress-axe'); - } - return updatedProjectJson; - }, - ); -} - -export default async function accessibilityGenerator( - tree: Tree, - options: AccessibilityGeneratorSchema, -) { - verifyPluginCanBeInstalled(tree, options.project); - - const normalizedOptions = normalizeOptions(tree, options); - if ( - hasGeneratorExecutedForProject( - tree, - options.project, - 'CypressAccessibility', - ) - ) - return false; - isGeneratorInExecutedListForProject( - tree, - options.project, - 'CypressInit', - true, - ); - - // generate acessiblity files - addFiles( - tree, - 'files', - __dirname, - normalizedOptions.cypressProject, - normalizedOptions, - ); - - // update ts config - updateTsConfig(tree, normalizedOptions.cypressProject); - - updateCypressConfig(tree, normalizedOptions.cypressProject); - - // add terminal logging funcitonality to e2e.ts - addTerminalLogging(tree, normalizedOptions.cypressProject); - - await formatFiles(tree); - - return updateDependencies(tree); -} diff --git a/packages/cypress/src/generators/accessibility/schema.d.ts b/packages/cypress/src/generators/accessibility/schema.d.ts deleted file mode 100644 index 7912ded5b..000000000 --- a/packages/cypress/src/generators/accessibility/schema.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface AccessibilityGeneratorSchema { - project: string; -} diff --git a/packages/cypress/src/generators/accessibility/schema.json b/packages/cypress/src/generators/accessibility/schema.json deleted file mode 100644 index a3bc7bcef..000000000 --- a/packages/cypress/src/generators/accessibility/schema.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "$schema": "http://json-schema.org/schema", - "$id": "Accessibility", - "title": "Ensono Stacks cypress Accessibility Generator", - "description": "The @ensono-stacks/cypress:accessibility generator scaffolds your existing initialised cypress project with example Accessibility tests and config.", - "type": "object", - "properties": { - "project": { - "type": "string", - "description": "The name of the project.", - "alias": "p", - "$default": { - "$source": "projectName" - }, - "x-prompt": "What is the name of the project for this component?" - } - }, - "required": [ - "project" - ] -} diff --git a/packages/cypress/src/generators/accessibility/utils/update-files.ts b/packages/cypress/src/generators/accessibility/utils/update-files.ts deleted file mode 100644 index 94b7f69eb..000000000 --- a/packages/cypress/src/generators/accessibility/utils/update-files.ts +++ /dev/null @@ -1,138 +0,0 @@ -import { tsMorphTree } from '@ensono-stacks/core'; -import { joinPathFragments, Tree } from '@nx/devkit'; -import { - MethodDeclaration, - ObjectLiteralExpression, - SyntaxKind, - ImportDeclarationStructure, - OptionalKind, -} from 'ts-morph'; - -export const terminalLogAxeBody = `cy.task( - 'log', - \`\${violations.length} accessibility violation\${ - violations.length === 1 ? '' : 's' - } \${violations.length === 1 ? 'was' : 'were'} detected\` - ); - // pluck specific keys to keep the table readable - const violationData = violations.map( - ({ id, impact, description, nodes }) => ({ - id, - impact, - description, - nodes: nodes.length, - }) - ); - - cy.task('table', violationData);`; - -export function addTerminalLogging(tree: Tree, cypressDirectory: string) { - const morphTree = tsMorphTree(tree); - const functionName = 'terminalLogAxe'; - const appNode = morphTree.addSourceFileAtPath( - joinPathFragments(cypressDirectory, 'src', 'support', 'e2e.ts'), - ); - - if (!appNode.getFunction(functionName)) { - appNode.addStatements( - ` -import { Result } from 'axe-core'; -import addContext from 'mochawesome/addContext'; - -const cypressGrep = require('@cypress/grep'); -cypressGrep(); - - -// Append screenshots on failure to test reports -Cypress.on('test:after:run', (test, runnable) => { - if (test.state === 'failed') { - const screenshot = \`../screenshots/\${Cypress.spec.name}/\${runnable.parent?.title} -- \${test.title} (failed).png\`; - // @ts-ignore - addContext({ test }, screenshot); - } -}); - -export function terminalLogAxe(violations: Result[]) { - cy.task( - 'log', - \`\${violations.length} accessibility violation\${violations.length === 1 ? '' : 's' - } \${violations.length === 1 ? 'was' : 'were'} detected\` - ); - // pluck specific keys to keep the table readable - const violationData = violations.map( - ({ id, impact, description, nodes }) => ({ - id, - impact, - description, - nodes: nodes.length, - }) - ); - - cy.task('table', violationData); - } - - `, - ); - - appNode.save(); - } -} - -export function updateCypressConfig(tree: Tree, project: string) { - const sourceFile = tsMorphTree(tree).addSourceFileAtPath( - joinPathFragments(project, 'cypress.config.ts'), - ); - const functionName = 'setupNodeEvents'; - const defineConfigExpression = sourceFile - .getDescendantsOfKind(SyntaxKind.CallExpression) - .find(callExpression => { - const expression = callExpression.getExpression(); - return expression && expression.getText() === 'defineConfig'; - }) - ?.getArguments()[0] as ObjectLiteralExpression; - if (!defineConfigExpression) { - throw new Error( - 'No defineConfig was found in the application cypress.config.ts file, have you created this using @ensono-stacks/cypress:init?', - ); - } - - const requiredProperty = defineConfigExpression - .getPropertyOrThrow('e2e') - .asKind(SyntaxKind.PropertyAssignment) - .getInitializerIfKindOrThrow(SyntaxKind.ObjectLiteralExpression); - - const setupNodeEventsMethod: MethodDeclaration = - requiredProperty - .getChildrenOfKind(SyntaxKind.MethodDeclaration) - .find( - methodDeclaration => - methodDeclaration.getName() === functionName, - ) || - requiredProperty.addMethod({ - name: functionName, - parameters: [ - { - name: 'on', - }, - { - name: 'config', - }, - ], - }); - setupNodeEventsMethod.insertStatements( - setupNodeEventsMethod.getStatements().length, - ` - on('task', { - log(message) { - console.log(message); - return null; - }, - table(message) { - console.table(message); - return null; - }, - }); - `, - ); - sourceFile.saveSync(); -} diff --git a/packages/cypress/src/generators/init-deployment/generator.spec.ts b/packages/cypress/src/generators/init-deployment/generator.spec.ts deleted file mode 100644 index b6471c914..000000000 --- a/packages/cypress/src/generators/init-deployment/generator.spec.ts +++ /dev/null @@ -1,114 +0,0 @@ -import { createNextApp } from '@ensono-stacks/test'; -// import { initDeploymentGenerator } from '@ensono-stacks/workspace'; -import { readJson, Tree } from '@nx/devkit'; -import YAML from 'yaml'; - -// eslint-disable-next-line @nx/enforce-module-boundaries, import/no-relative-packages -import generator from './generator'; - -const applicationName = 'application'; - -xdescribe('cypress generator', () => { - let appTree: Tree; - - beforeAll(async () => { - appTree = await createNextApp(applicationName); - }); - - it('returns false if no prerequisite present', async () => { - const gen = await generator(appTree); - expect(gen).toBe(false); - }); - - describe('generator should manipulate deployment files as expected', () => { - beforeAll(async () => { - // await initDeploymentGenerator(appTree, { - // pipelineRunner: 'taskctl', - // }); - await generator(appTree); - }); - - it('should update nx.json and tag executed generator true', async () => { - const nxJson = readJson(appTree, 'nx.json'); - - expect( - nxJson.stacks.executedGenerators.workspace.includes( - 'CypressInitDeployment', - ), - ).toBe(true); - }); - - it('should run successfully with default options', async () => { - const taskctlYAML = YAML.parse( - appTree.read('taskctl.yaml', 'utf8'), - ); - expect(taskctlYAML.pipelines.dev).toContainEqual({ - task: 'e2e:ci', - depends_on: 'build', - }); - expect(taskctlYAML.pipelines.fe).toContainEqual({ - task: 'e2e:ci', - depends_on: 'build', - }); - expect(taskctlYAML.pipelines.nonprod).toContainEqual({ - task: 'e2e:ci', - depends_on: 'test:ci', - }); - expect(taskctlYAML.pipelines.prod).toContainEqual({ - task: 'e2e:ci', - depends_on: 'test:ci', - }); - }, 100_000); - - it('should alter azure devops stages file that is generated by workspace', async () => { - const stages = YAML.parse( - appTree.read('build/azDevOps/azuredevops-stages.yaml', 'utf8'), - ); - - expect(stages.stages[0]?.jobs[0]?.steps[5]).toEqual({ - task: 'Bash@3', - displayName: 'Check test-results Folder', - condition: 'succeededOrFailed()', - inputs: { - targetType: 'inline', - script: - 'if [ -d $SYSTEM_DEFAULTWORKINGDIRECTORY/test-results ]; then\n' + - ' echo "##vso[task.setVariable variable=HASTESTRESULTS]true"\n' + - 'fi', - }, - }); - - expect(stages.stages[0]?.jobs[0]?.steps[6]).toEqual({ - task: 'Bash@3', - condition: - "and(succeededOrFailed(),eq(variables.HASTESTRESULTS, 'true'))", - displayName: 'Generate Reports', - inputs: { - targetType: 'inline', - script: 'npx nx affected --base="$BASE_SHA" --target=html-report --configuration=ci --parallel=1', - }, - }); - - expect(stages.stages[0]?.jobs[0]?.steps[7]).toEqual({ - task: 'PublishTestResults@2', - condition: - "and(succeededOrFailed(),eq(variables.HASTESTRESULTS, 'true'))", - inputs: { - testResultsFormat: 'JUnit', - testResultsFiles: 'test-results/**/*.xml', - }, - }); - expect(stages.stages[0]?.jobs[0]?.steps[8]).toEqual({ - task: 'PublishPipelineArtifact@1', - condition: - "and(succeededOrFailed(),eq(variables.HASTESTRESULTS, 'true'))", - inputs: { - targetPath: - '$(System.DefaultWorkingDirectory)/test-results', - artifact: 'testresults', - publishLocation: 'pipeline', - }, - }); - }); - }); -}); diff --git a/packages/cypress/src/generators/init-deployment/generator.ts b/packages/cypress/src/generators/init-deployment/generator.ts deleted file mode 100644 index 485f271cb..000000000 --- a/packages/cypress/src/generators/init-deployment/generator.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { - executedDependantGenerator, - hasGeneratorExecutedForWorkspace, - verifyPluginCanBeInstalled, -} from '@ensono-stacks/core'; -import { formatFiles, Tree } from '@nx/devkit'; - -import { updateAzureDevopsStages } from './utils/update-azdevops-build'; -import { updateTaskctlYaml, updateTasksYaml } from './utils/update-tasks-yamls'; - -// eslint-disable-next-line consistent-return -export default async function initDeploymentGenerator(tree: Tree) { - verifyPluginCanBeInstalled(tree); - - if (!executedDependantGenerator(tree, 'WorkspaceDeployment')) return false; - if (hasGeneratorExecutedForWorkspace(tree, 'CypressInitDeployment')) - return false; - - updateTaskctlYaml(tree); - updateTasksYaml(tree); - updateAzureDevopsStages(tree); - - await formatFiles(tree); -} diff --git a/packages/cypress/src/generators/init-deployment/schema.d.ts b/packages/cypress/src/generators/init-deployment/schema.d.ts deleted file mode 100644 index b0bfa1509..000000000 --- a/packages/cypress/src/generators/init-deployment/schema.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -// eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface InitDeploymentGeneratorSchema {} diff --git a/packages/cypress/src/generators/init-deployment/schema.json b/packages/cypress/src/generators/init-deployment/schema.json deleted file mode 100644 index a7bb41f17..000000000 --- a/packages/cypress/src/generators/init-deployment/schema.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "$schema": "http://json-schema.org/schema", - "$id": "InitDeployment", - "title": "Ensono Stacks Cypress Init Deployment Generator", - "description": "The @ensono-stacks/cypress:init-deployment generator adds the relevant pipeline and infrastructure code to your workspace.", - "type": "object", - "properties": {}, - "required": [] -} diff --git a/packages/cypress/src/generators/init-deployment/utils/update-azdevops-build.ts b/packages/cypress/src/generators/init-deployment/utils/update-azdevops-build.ts deleted file mode 100644 index cb76f0235..000000000 --- a/packages/cypress/src/generators/init-deployment/utils/update-azdevops-build.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { Tree } from '@nx/devkit'; -import YAML from 'yaml'; - -export function updateAzureDevopsStages(tree: Tree) { - if (tree.exists('build/azDevOps/azuredevops-stages.yaml')) { - const stages = YAML.parse( - tree.read('build/azDevOps/azuredevops-stages.yaml', 'utf8'), - ); - if (!stages) { - return; - } - - stages?.stages[0]?.jobs[0]?.steps.push({ - task: 'Bash@3', - displayName: 'Check test-results Folder', - condition: 'succeededOrFailed()', - inputs: { - targetType: 'inline', - script: - 'if [ -d $SYSTEM_DEFAULTWORKINGDIRECTORY/test-results ]; then\n' + - ' echo "##vso[task.setVariable variable=HASTESTRESULTS]true"\n' + - 'fi', - }, - }); - - stages?.stages[0]?.jobs[0]?.steps.push({ - task: 'Bash@3', - condition: - "and(succeededOrFailed(),eq(variables.HASTESTRESULTS, 'true'))", - displayName: 'Generate Reports', - inputs: { - targetType: 'inline', - script: 'npx nx affected --base="$BASE_SHA" --target=html-report --configuration=ci --parallel=1', - }, - }); - - stages?.stages[0]?.jobs[0]?.steps.push({ - task: 'PublishTestResults@2', - condition: - "and(succeededOrFailed(),eq(variables.HASTESTRESULTS, 'true'))", - inputs: { - testResultsFormat: 'JUnit', - testResultsFiles: 'test-results/**/*.xml', - }, - }); - - stages?.stages[0]?.jobs[0]?.steps.push({ - task: 'PublishPipelineArtifact@1', - condition: - "and(succeededOrFailed(),eq(variables.HASTESTRESULTS, 'true'))", - inputs: { - targetPath: '$(System.DefaultWorkingDirectory)/test-results', - artifact: 'testresults', - publishLocation: 'pipeline', - }, - }); - - tree.write( - 'build/azDevOps/azuredevops-stages.yaml', - YAML.stringify(stages), - ); - } -} diff --git a/packages/cypress/src/generators/init-deployment/utils/update-tasks-yamls.ts b/packages/cypress/src/generators/init-deployment/utils/update-tasks-yamls.ts deleted file mode 100644 index 9a9a07878..000000000 --- a/packages/cypress/src/generators/init-deployment/utils/update-tasks-yamls.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { Tree } from '@nx/devkit'; -import YAML from 'yaml'; - -export function updateTasksYaml(tree: Tree) { - if (!tree.exists('build/taskctl/tasks.yaml')) { - return; - } - - const tasks = YAML.parse(tree.read('build/taskctl/tasks.yaml', 'utf8')); - if (tasks.tasks) { - // Add e2e tasks - tasks.tasks = { - ...tasks.tasks, - 'e2e:ci': { - description: 'Run e2e tests in ci', - command: [ - 'npx nx affected --base="$BASE_SHA" --target=e2e --parallel=1', - ], - }, - html: { - description: 'Generate html reports for tests', - command: [ - 'npx nx affected --base="$BASE_SHA" --target=html-report --configuration=ci --parallel=1', - ], - }, - }; - } - - tree.write('build/taskctl/tasks.yaml', YAML.stringify(tasks)); -} - -export function updateTaskctlYaml(tree: Tree) { - if (!tree.exists('taskctl.yaml')) { - return; - } - - const taskctl = YAML.parse(tree.read('taskctl.yaml', 'utf8')); - taskctl.pipelines.dev = [ - { task: 'lint' }, - { task: 'build', depends_on: 'lint' }, - { task: 'e2e:ci', depends_on: 'build' }, - { task: 'version', depends_on: 'e2e:ci' }, - { task: 'terraform', depends_on: 'version' }, - { task: 'helm', depends_on: 'terraform' }, - ]; - taskctl.pipelines.fe = [ - { task: 'lint' }, - { task: 'build', depends_on: 'lint' }, - { task: 'e2e:ci', depends_on: 'build' }, - { task: 'html', depends_on: 'e2e:ci' }, - { task: 'version', depends_on: 'e2e:ci' }, - ]; - taskctl.pipelines.nonprod = [ - { task: 'lint:ci' }, - { task: 'build:ci', depends_on: 'lint:ci' }, - { task: 'test:ci', depends_on: 'build:ci' }, - { task: 'e2e:ci', depends_on: 'test:ci' }, - { task: 'version:nonprod', depends_on: 'e2e:ci' }, - { task: 'terraform:nonprod', depends_on: 'version:nonprod' }, - { task: 'helm:nonprod', depends_on: 'terraform:nonprod' }, - ]; - taskctl.pipelines.prod = [ - { task: 'build:ci' }, - { task: 'test:ci', depends_on: 'build:ci' }, - { task: 'e2e:ci', depends_on: 'test:ci' }, - { task: 'version:prod', depends_on: 'e2e:ci' }, - { task: 'terraform:prod', depends_on: 'version:prod' }, - { task: 'helm:prod', depends_on: 'terraform:prod' }, - ]; - - tree.write('taskctl.yaml', YAML.stringify(taskctl)); -} diff --git a/packages/cypress/src/generators/init/__snapshots__/generator.spec.ts.snap b/packages/cypress/src/generators/init/__snapshots__/generator.spec.ts.snap deleted file mode 100644 index 063f64efb..000000000 --- a/packages/cypress/src/generators/init/__snapshots__/generator.spec.ts.snap +++ /dev/null @@ -1,101 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`should run successfully with default options should move the tsconfig.cy.json into the cypress directory and configure it has configured the new tsconfig.json within the cypress directory: apps/application-e2e/src/tsconfig.json 1`] = ` -"{ - "extends": "../tsconfig.json", - "compilerOptions": { - "allowJs": true, - "outDir": "../../dist/out-tsc", - "module": "commonjs", - "types": ["cypress", "node"], - "sourceMap": false - }, - "include": [ - "**/*.ts", - "**/*.js", - "../cypress.config.ts", - "../**/*.cy.ts", - "../**/*.cy.js", - "../**/*.d.ts" - ], - "exclude": ["cypress/**/**", "cypress.config.ts"] -} -" -`; - -exports[`should run successfully with default options should set up the example files: apps/application-e2e/src/fixtures/example.json 1`] = ` -"{ - "name": "Using fixtures to represent data", - "email": "hello@cypress.io", - "body": "Fixtures are a great way to mock data for responses to routes" -} -" -`; - -exports[`should run successfully with default options should set up the example files: apps/application-e2e/src/support/commands.ts 1`] = ` -"declare namespace Cypress { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - interface Chainable { - login(email: string, password: string): void; - } -} - -// -- This is a parent command -- -Cypress.Commands.add('login', (email, password) => { - console.log('Custom command example: Login', email, password); -}); -// -// -- This is a child command -- -// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) -// -// -// -- This is a dual command -- -// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) -// -// -// -- This will overwrite an existing command -- -// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... }) -" -`; - -exports[`should run successfully with default options should update the project cypress config: apps/application-e2e/cypress.config.ts 1`] = ` -"import { nxE2EPreset } from '@nx/cypress/plugins/cypress-preset'; - -import { defineConfig } from 'cypress'; - -const appName = process.env.NX_TASK_TARGET_PROJECT as string; -const outputFolderForProject = process.env.CI - ? \`../../test-results/\${appName}\` - : 'test-results'; - -export default defineConfig({ - e2e: { ...nxE2EPreset(__filename, { cypressDir: 'src' }) }, - reporter: '../../node_modules/cypress-multi-reporters', - reporterOptions: { - reporterEnabled: !process.env.CI - ? 'spec' - : 'spec, mocha-junit-reporter, mochawesome', - mochaJunitReporterReporterOptions: { - mochaFile: outputFolderForProject.concat( - \`/downloads/junit-report/results-\${appName}-[hash].xml\` - ), - }, - mochawesomeReporterOptions: { - charts: true, - overwrite: false, - html: false, - json: true, - reportDir: outputFolderForProject.concat('/downloads/reports-json-file'), - reportFilename: '[name].html', - embeddedScreenshots: true, - inlineAssets: true, - }, - }, -}); -" -`; - -exports[`should run successfully with default options should update the support e2e file: apps/application-e2e/src/support/e2e.ts 1`] = ` -"import './commands'; -" -`; diff --git a/packages/cypress/src/generators/init/files/cypress.config.ts__template__ b/packages/cypress/src/generators/init/files/cypress.config.ts__template__ deleted file mode 100644 index 91a9c651a..000000000 --- a/packages/cypress/src/generators/init/files/cypress.config.ts__template__ +++ /dev/null @@ -1,33 +0,0 @@ -import { nxE2EPreset } from '@nx/cypress/plugins/cypress-preset'; - -import { defineConfig } from 'cypress'; - -const appName = process.env.NX_TASK_TARGET_PROJECT as string; -const outputFolderForProject = process.env.CI - ? `../../test-results/${appName}` - : 'test-results'; - -export default defineConfig({ - e2e: { ...nxE2EPreset(__filename, { cypressDir: 'src' }) }, - reporter: '../../node_modules/cypress-multi-reporters', - reporterOptions: { - reporterEnabled: !process.env.CI - ? 'spec' - : 'spec, mocha-junit-reporter, mochawesome', - mochaJunitReporterReporterOptions: { - mochaFile: outputFolderForProject.concat( - `/downloads/junit-report/results-${appName}-[hash].xml` - ), - }, - mochawesomeReporterOptions: { - charts: true, - overwrite: false, - html: false, - json: true, - reportDir: outputFolderForProject.concat('/downloads/reports-json-file'), - reportFilename: '[name].html', - embeddedScreenshots: true, - inlineAssets: true, - }, - }, -}); \ No newline at end of file diff --git a/packages/cypress/src/generators/init/generator.spec.ts b/packages/cypress/src/generators/init/generator.spec.ts deleted file mode 100644 index 5933b6b5f..000000000 --- a/packages/cypress/src/generators/init/generator.spec.ts +++ /dev/null @@ -1,253 +0,0 @@ -import { tsMorphTree } from '@ensono-stacks/core'; -import { checkFilesExistInTree, createNextApp } from '@ensono-stacks/test'; -import { joinPathFragments, readJson, Tree } from '@nx/devkit'; - -import generator from './generator'; -import { CypressGeneratorSchema } from './schema'; -import { checkOneOccurence } from '../../utils/test-utils'; -import { - CYPRESS_VERSION, - CYPRESSMULTIREPORTERS_VERSION, - MOCHAWESOME_VERSION, - MOCHAWESOMEJUNITREPORTER_VERSION, - MOCHAWESOMEMERGE_VERSION, - CYPRESSGREP_VERSION, -} from '../../versions'; - -const applicationName = 'application'; -const applicationDirectory = `apps/${applicationName}`; -const E2EApplicationDirectory = `apps/${applicationName}-e2e`; - -let appTree: Tree; -let options: CypressGeneratorSchema; - -jest.mock('@nx/devkit', () => { - const actual = jest.requireActual('@nx/devkit'); - - return { - ...actual, - getProjects: jest.fn( - () => - new Map([ - [ - applicationName, - { - root: applicationDirectory, - sourceRoot: applicationDirectory, - name: applicationName, - }, - ], - ]), - ), - }; -}); - -function snapshotFiles(tree, ...files: string[]) { - expect(() => checkFilesExistInTree(tree, ...files)).not.toThrowError(); - const project = tsMorphTree(tree); - files.forEach(file => { - expect(project.addSourceFileAtPath(file).getText()).toMatchSnapshot( - file, - ); - }); -} - -describe('cypress generator', () => { - beforeEach(async () => { - options = { - project: applicationName, - }; - appTree = await createNextApp(options.project); - }); - - it('should resolve false if the project already exists', async () => { - await generator(appTree, options); - await expect(generator(appTree, options)).resolves.toBe(false); - }, 100_000); - - describe('executedGenerators', () => { - beforeEach(async () => { - await generator(appTree, options); - }); - - it('should update nx.json and tag executed generator true', async () => { - const nxJson = readJson(appTree, 'nx.json'); - - expect( - nxJson.stacks.executedGenerators.project[ - options.project - ].includes('CypressInit'), - ).toBe(true); - }); - - it('should return false from method and exit generator if already executed', async () => { - const gen = await generator(appTree, { - ...options, - }); - - expect(gen).toBe(false); - }); - }); -}); - -describe('should run successfully with default options', () => { - let project; - - beforeAll(async () => { - options = { - project: applicationName, - }; - appTree = await createNextApp(options.project); - await generator(appTree, options); - project = tsMorphTree(appTree); - }); - - it('should install deps into package.json', () => { - const packageJson = readJson(appTree, 'package.json'); - expect(packageJson?.devDependencies).toMatchObject( - expect.objectContaining({ - cypress: CYPRESS_VERSION, - 'cypress-multi-reporters': CYPRESSMULTIREPORTERS_VERSION, - mochawesome: MOCHAWESOME_VERSION, - 'mochawesome-merge': MOCHAWESOMEMERGE_VERSION, - 'mocha-junit-reporter': MOCHAWESOMEJUNITREPORTER_VERSION, - '@cypress/grep': CYPRESSGREP_VERSION, - }), - ); - }); - - it('should update the applications eslintrc.json', () => { - const eslintrc = readJson( - appTree, - joinPathFragments(E2EApplicationDirectory, '.eslintrc.json'), - ); - - expect( - checkOneOccurence( - eslintrc.overrides[0].parserOptions.project, - joinPathFragments( - E2EApplicationDirectory, - 'tsconfig(.*)?.json', - ), - ), - ).toBeTruthy(); - }); - - it('should update the gitignore', () => { - // expect .gitignore entries to be added - const gitIgnoreFile = appTree.read('/.gitignore', 'utf8'); - expect(gitIgnoreFile).toContain('**/test-results'); - }); - - it('should update the project cypress config', () => { - snapshotFiles( - appTree, - joinPathFragments( - `${E2EApplicationDirectory}`, - 'cypress.config.ts', - ), - ); - }); - - it('should update the project.json with the html-report target', () => { - const projectJson = readJson( - appTree, - joinPathFragments(`${E2EApplicationDirectory}`, 'project.json'), - ); - expect(projectJson.targets.e2e).toBeTruthy(); - - // update this to include the actual app name - const expectedJson = { - executor: 'nx:run-commands', - options: { - commands: [ - 'mochawesome-merge reports-json-file/app.json -o merged-html-report.json', - 'marge merged-html-report.json ./ --inline', - ], - parallel: false, - cwd: `${E2EApplicationDirectory}/test-results/downloads`, - }, - configurations: { - ci: { - cwd: 'test-results/application-e2e/downloads', - }, - }, - }; - - expect(projectJson.targets['html-report']).toBeTruthy(); - expect(projectJson.targets['html-report']).toEqual(expectedJson); - }); - - it('should set up the example files', () => { - snapshotFiles( - appTree, - joinPathFragments( - E2EApplicationDirectory, - 'src', - 'fixtures', - 'example.json', - ), - joinPathFragments( - E2EApplicationDirectory, - 'src', - 'support', - 'commands.ts', - ), - ); - }); - - it('should update the support e2e file', () => { - snapshotFiles( - appTree, - joinPathFragments( - E2EApplicationDirectory, - 'src', - 'support', - 'e2e.ts', - ), - ); - }); - - describe('should move the tsconfig.cy.json into the cypress directory and configure it', () => { - it('has removed the tsconfig.cy.json from the app directory', () => { - expect( - appTree.exists( - joinPathFragments(applicationDirectory, 'tsconfig.cy.json'), - ), - ).toBeFalsy(); - }); - - it('has excluded cypress from the application tsconfig.json', () => { - const configJson = readJson( - appTree, - joinPathFragments( - E2EApplicationDirectory, - 'src', - 'tsconfig.json', - ), - ); - expect( - checkOneOccurence(configJson.exclude, 'cypress/**/**'), - ).toBeTruthy(); - expect( - checkOneOccurence(configJson.exclude, 'cypress.config.ts'), - ).toBeTruthy(); - }); - - it('has configured the new tsconfig.json within the cypress directory', () => { - snapshotFiles( - appTree, - joinPathFragments( - E2EApplicationDirectory, - 'src', - 'tsconfig.json', - ), - ); - }); - }); - - it('should update the tsconfig.base.json', () => { - const tsconfig = readJson(appTree, 'tsconfig.base.json'); - expect(tsconfig.compilerOptions.sourceMap).toBe(false); - }); -}); diff --git a/packages/cypress/src/generators/init/generator.ts b/packages/cypress/src/generators/init/generator.ts deleted file mode 100644 index 348e55791..000000000 --- a/packages/cypress/src/generators/init/generator.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { - addIgnoreEntry, - deploymentGeneratorMessage, - hasGeneratorExecutedForProject, - verifyPluginCanBeInstalled, -} from '@ensono-stacks/core'; -import { cypressE2EConfigurationGenerator } from '@nx/cypress'; -import { CypressE2EConfigSchema } from '@nx/cypress/src/generators/configuration/configuration'; -import { - formatFiles, - Tree, - readProjectConfiguration, - addDependenciesToPackageJson, - runTasksInSerial, -} from '@nx/devkit'; -import { Linter } from '@nx/eslint'; -import { libraryGenerator } from '@nx/js'; - -import { CypressGeneratorSchema } from './schema'; -import { - updateBaseTsConfig, - updateApplicationLintFile, - updateTsConfig, -} from './utils/update-files'; -import { updateProjectJsonWithHtmlReport } from './utils/update-targets'; -import { addFiles, normalizeOptions } from '../../utils/test-utils'; -import { - CYPRESS_VERSION, - CYPRESSMULTIREPORTERS_VERSION, - MOCHAWESOME_VERSION, - MOCHAWESOMEJUNITREPORTER_VERSION, - MOCHAWESOMEMERGE_VERSION, - NXCYPRESS_VERSION, - CYPRESSGREP_VERSION, -} from '../../versions'; - -function updateDependencies(tree) { - return addDependenciesToPackageJson( - tree, - {}, - { - cypress: CYPRESS_VERSION, - '@nx/cypress': NXCYPRESS_VERSION, - 'cypress-multi-reporters': CYPRESSMULTIREPORTERS_VERSION, - mochawesome: MOCHAWESOME_VERSION, - 'mochawesome-merge': MOCHAWESOMEMERGE_VERSION, - 'mocha-junit-reporter': MOCHAWESOMEJUNITREPORTER_VERSION, - '@cypress/grep': CYPRESSGREP_VERSION, - }, - ); -} - -export default async function initGenerator( - tree: Tree, - options: CypressGeneratorSchema, -) { - verifyPluginCanBeInstalled(tree, options.project); - - if (hasGeneratorExecutedForProject(tree, options.project, 'CypressInit')) - return false; - const normalizedOptions = normalizeOptions(tree, options); - - const projectE2EName = `${normalizedOptions.project}-e2e`; - - const cypressGeneratorConfiguration: CypressE2EConfigSchema = { - project: projectE2EName, - directory: 'src', - linter: Linter.EsLint, - devServerTarget: `${normalizedOptions.projectName}:serve-static`, - }; - - await libraryGenerator(tree, { - name: projectE2EName, - directory: `apps/${projectE2EName}`, - projectNameAndRootFormat: 'as-provided', - }); - - await cypressE2EConfigurationGenerator(tree, cypressGeneratorConfiguration); - - // add custom reporters in cypress.config - addFiles( - tree, - 'files', - __dirname, - normalizedOptions.cypressProject, - normalizedOptions, - ); - - // update application eslint.rc - updateApplicationLintFile(tree, normalizedOptions.cypressProject); - // update ts config - updateTsConfig(tree, normalizedOptions.cypressProject); - updateBaseTsConfig(tree); - - // update targets - updateProjectJsonWithHtmlReport( - normalizedOptions.cypressProject, - readProjectConfiguration(tree, normalizedOptions.projectName), - tree, - ); - // update git ignore - addIgnoreEntry(tree, '.gitignore', 'Cypress', ['**/test-results']); - - await formatFiles(tree); - - return runTasksInSerial(updateDependencies(tree), () => - deploymentGeneratorMessage( - tree, - 'nx g @ensono-stacks/cypress:init-deployment', - ), - ); -} diff --git a/packages/cypress/src/generators/init/schema.d.ts b/packages/cypress/src/generators/init/schema.d.ts deleted file mode 100644 index 72a28bea2..000000000 --- a/packages/cypress/src/generators/init/schema.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface CypressGeneratorSchema { - project: string; -} diff --git a/packages/cypress/src/generators/init/schema.json b/packages/cypress/src/generators/init/schema.json deleted file mode 100644 index f04ab16ad..000000000 --- a/packages/cypress/src/generators/init/schema.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "$schema": "http://json-schema.org/schema", - "$id": "Init", - "title": "Ensono Stacks Cypress Init Generator", - "description": "The @ensono-stacks/cypress:init generator initialises your cypress project with additional stacks configuration.", - "type": "object", - "properties": { - "project": { - "type": "string", - "description": "The name of the project.", - "alias": "p", - "$default": { - "$source": "projectName" - }, - "x-prompt": "What app would you like to generate a test project for?" - } - }, - "required": [ - "project" - ] -} diff --git a/packages/cypress/src/generators/init/utils/update-files.ts b/packages/cypress/src/generators/init/utils/update-files.ts deleted file mode 100644 index 9f920b002..000000000 --- a/packages/cypress/src/generators/init/utils/update-files.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { joinPathFragments, Tree, updateJson } from '@nx/devkit'; - -function findOverride( - json: Array, - files: Array, - errorMessage: string, -) { - return ( - json.find(element => - files.every(value => element.files.includes(value)), - ) || - (() => { - throw new Error(errorMessage); - }) - ); -} - -export function updateApplicationLintFile(tree: Tree, path: string) { - updateJson(tree, joinPathFragments(path, '.eslintrc.json'), eslintjson => { - const updatedProjectJson = { ...eslintjson }; - const override = findOverride( - updatedProjectJson.overrides, - ['*.ts', '*.tsx', '*.js', '*.jsx'], - 'Unable to update the application lint file with with parser options for cypress', - ); - if (!override.parserOptions) { - override.parserOptions = {}; - } - if (!override.parserOptions.project) { - override.parserOptions.project = []; - } - const requiredEntry = joinPathFragments(path, 'tsconfig(.*)?.json'); - if (!override.parserOptions.project.includes(requiredEntry)) { - override.parserOptions.project.push(requiredEntry); - } - return updatedProjectJson; - }); -} - -export function updateTsConfig(tree: Tree, project: string) { - updateJson( - tree, - joinPathFragments(project, 'src', 'tsconfig.json'), - tsConfigJson => { - const updatedProjectJson = { ...tsConfigJson }; - - if (updatedProjectJson.exclude) { - updatedProjectJson.exclude.push( - 'cypress/**/**', - 'cypress.config.ts', - ); - } else { - updatedProjectJson.exclude = [ - 'cypress/**/**', - 'cypress.config.ts', - ]; - } - return updatedProjectJson; - }, - ); -} - -export function updateBaseTsConfig(tree: Tree) { - // Source map set to false due to Cypress hardcoding inlineSourceMap to true - updateJson(tree, 'tsconfig.base.json', tsConfigJson => { - const updatedProjectJson = { ...tsConfigJson }; - updatedProjectJson.compilerOptions['sourceMap'] = false; - return updatedProjectJson; - }); -} diff --git a/packages/cypress/src/generators/init/utils/update-targets.ts b/packages/cypress/src/generators/init/utils/update-targets.ts deleted file mode 100644 index 985ead2ed..000000000 --- a/packages/cypress/src/generators/init/utils/update-targets.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { - joinPathFragments, - ProjectConfiguration, - Tree, - updateJson, -} from '@nx/devkit'; - -export function updateProjectJsonWithHtmlReport( - projectRoot: string, - project: ProjectConfiguration, - tree: Tree, -) { - updateJson( - tree, - joinPathFragments(`${project.sourceRoot}-e2e`, 'project.json'), - projectJson => { - const updatedProjectJson = { ...projectJson }; - - if (!projectJson.targets['html-report']) { - updatedProjectJson.targets['html-report'] = { - executor: 'nx:run-commands', - options: { - commands: [ - 'mochawesome-merge reports-json-file/app.json -o merged-html-report.json', - 'marge merged-html-report.json ./ --inline', - ], - parallel: false, - cwd: `${projectRoot}/test-results/downloads`, - }, - configurations: { - ci: { - cwd: `test-results/${project.name}-e2e/downloads`, - }, - }, - }; - } - - return updatedProjectJson; - }, - ); -} diff --git a/packages/cypress/src/index.ts b/packages/cypress/src/index.ts deleted file mode 100644 index 5871e2003..000000000 --- a/packages/cypress/src/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export { default as initGenerator } from './generators/init/generator'; -// export { default as initDeploymentGenerator } from './generators/init-deployment/generator'; -// export { default as visualRegressionGenerator } from './generators/visual-regression/generator'; -// export { default as visualRegressionDeploymentGenerator } from './generators/visual-regression-deployment/generator'; -export { default as accessibilityGenerator } from './generators/accessibility/generator'; diff --git a/packages/cypress/src/utils/test-utils.ts b/packages/cypress/src/utils/test-utils.ts deleted file mode 100644 index ef5a9539a..000000000 --- a/packages/cypress/src/utils/test-utils.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { - generateFiles, - getProjects, - joinPathFragments, - offsetFromRoot, - Tree, -} from '@nx/devkit'; -import path from 'path'; - -import { CypressGeneratorSchema } from '../generators/init/schema'; - -export interface NormalizedSchema extends CypressGeneratorSchema { - projectName: string; - projectRoot: string; - cypressProject: string; -} - -export function checkOneOccurence(array: any[], value: any) { - return array.filter(element => element === value).length === 1; -} - -export function normalizeOptions( - tree: Tree, - options: CypressGeneratorSchema, -): NormalizedSchema { - const project = getProjects(tree).get(options.project); - - if (!project) { - throw new Error(`${options.project} does not exist.`); - } - - return { - ...options, - projectName: project?.name as string, - projectRoot: project?.sourceRoot as string, - cypressProject: `${project?.sourceRoot}-e2e`, - }; -} - -export function addFiles( - tree: Tree, - source: string, - dirname: string, - destination: string, - options: NormalizedSchema, -) { - const templateOptions = { - ...options, - offsetFromRoot: offsetFromRoot(options.projectRoot), - template: '', - }; - - generateFiles( - tree, - path.join(dirname, source), - destination, - templateOptions, - ); -} diff --git a/packages/cypress/src/versions.ts b/packages/cypress/src/versions.ts deleted file mode 100644 index a0c4c09e6..000000000 --- a/packages/cypress/src/versions.ts +++ /dev/null @@ -1,9 +0,0 @@ -export const CYPRESS_VERSION = '13.8.1'; -export const NXCYPRESS_VERSION = '18.3.4'; -export const CYPRESSMULTIREPORTERS_VERSION = '1.6.4'; -export const MOCHAWESOME_VERSION = '7.1.3'; -export const MOCHAWESOMEMERGE_VERSION = '4.3.0'; -export const MOCHAWESOMEJUNITREPORTER_VERSION = '2.2.1'; -export const AXECORE_VERSION = '4.9.0'; -export const CYPRESSAXE_VERSION = '1.5.0'; -export const CYPRESSGREP_VERSION = '4.0.1'; diff --git a/packages/cypress/tsconfig.json b/packages/cypress/tsconfig.json deleted file mode 100644 index fdc5ae37f..000000000 --- a/packages/cypress/tsconfig.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "extends": "../../tsconfig.base.json", - "compilerOptions": { - "module": "commonjs" - }, - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.lib.json" - }, - { - "path": "./tsconfig.spec.json" - } - ] -} diff --git a/packages/cypress/tsconfig.lib.json b/packages/cypress/tsconfig.lib.json deleted file mode 100644 index 87eef71ad..000000000 --- a/packages/cypress/tsconfig.lib.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../dist/out-tsc", - "declaration": true, - "types": ["node"] - }, - "include": ["src/**/*.ts", "../../tools/nx.d.ts"], - "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"] -} diff --git a/packages/cypress/tsconfig.spec.json b/packages/cypress/tsconfig.spec.json deleted file mode 100644 index 257d70dfc..000000000 --- a/packages/cypress/tsconfig.spec.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../dist/out-tsc", - "module": "commonjs", - "types": ["jest", "node"] - }, - "include": [ - "jest.config.ts", - "src/**/*.test.ts", - "src/**/*.spec.ts", - "src/**/*.d.ts", - "../../tools/nx.d.ts" - ] -} diff --git a/packages/playwright/README.md b/packages/playwright/README.md index 7a7fe8cb1..6738eeae3 100644 --- a/packages/playwright/README.md +++ b/packages/playwright/README.md @@ -44,4 +44,4 @@ Run the following to publish the NPM package ```bash nx publish playwright -``` +``` \ No newline at end of file diff --git a/tsconfig.base.json b/tsconfig.base.json index 54e4a4a5f..7b4153967 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -23,7 +23,6 @@ "@ensono-stacks/e2e": ["packages/common/e2e/src/index.ts"], "@ensono-stacks/logger": ["packages/logger/src/index.ts"], "@ensono-stacks/next": ["packages/next/src/index.ts"], - "@ensono-stacks/cypress": ["packages/cypress/src/index.ts"], "@ensono-stacks/playwright": ["packages/playwright/src/index.ts"], "@ensono-stacks/rest-client": ["packages/rest-client/src/index.ts"], "@ensono-stacks/test": ["packages/common/test/src/index.ts"],