diff --git a/.eslintignore b/.eslintignore index 3de1d944b361..088756bc013e 100644 --- a/.eslintignore +++ b/.eslintignore @@ -42,7 +42,3 @@ npm/webpack-preprocessor/examples/use-babelrc/cypress/integration/spec.js **/.git /npm/react/bin/* -/npm/react/**/coverage -**/.next/** -/npm/create-cypress-tests/initial-template -/npm/create-cypress-tests/**/*.template.* diff --git a/.gitignore b/.gitignore index 45bd54d4eed0..c6889fcd6245 100644 --- a/.gitignore +++ b/.gitignore @@ -26,7 +26,7 @@ npm/**/cypress/screenshots # from example packages/example/app packages/example/build -packages/example/cypress/integration +packages/example/cypress # from server packages/server/.cy @@ -39,10 +39,6 @@ packages/server/test/support/fixtures/server/libs /npm/react/bin/* /npm/react/cypress/videos -# from npm/create-cypress-tests -/npm/create-cypress-tests/initial-template -/npm/create-cypress-tests/src/test-output - # Building app binary scripts/support package-lock.json diff --git a/appveyor.yml b/appveyor.yml index 7a735cdea444..ac1436e71a56 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,7 +2,7 @@ branches: only: - master - develop - - v6.0-release + - revert-create-cypress-tests - /win*/ # https://www.appveyor.com/docs/lang/nodejs-iojs/ diff --git a/circle.yml b/circle.yml index a62484880223..19809b344032 100644 --- a/circle.yml +++ b/circle.yml @@ -958,17 +958,6 @@ jobs: command: yarn test working_directory: npm/react/<> - - npm-create-cypress-tests: - <<: *defaults - steps: - - attach_workspace: - at: ~/ - - run: yarn workspace create-cypress-tests build - - run: - name: Run unit test - command: yarn workspace create-cypress-tests test - npm-eslint-plugin-dev: <<: *defaults steps: @@ -1799,10 +1788,6 @@ linux-workflow: &linux-workflow requires: - npm-react - - npm-create-cypress-tests: - requires: - - build - - npm-eslint-plugin-dev: requires: - build diff --git a/npm/create-cypress-tests/.eslintrc b/npm/create-cypress-tests/.eslintrc deleted file mode 100644 index 08df16eaf0d4..000000000000 --- a/npm/create-cypress-tests/.eslintrc +++ /dev/null @@ -1,38 +0,0 @@ -{ - "plugins": [ - "cypress", - "@cypress/dev" - ], - "extends": [ - "plugin:@cypress/dev/general", - "plugin:@cypress/dev/tests" - ], - "parser": "@typescript-eslint/parser", - "env": { - "cypress/globals": true - }, - "rules": { - "no-console": "off", - "mocha/no-global-tests": "off", - "@typescript-eslint/no-unused-vars": "off" - }, - "overrides": [ - { - "files": [ - "lib/*" - ], - "rules": { - "no-console": 1 - } - }, - { - "files": [ - "**/*.json" - ], - "rules": { - "quotes": "off", - "comma-dangle": "off" - } - } - ] -} diff --git a/npm/create-cypress-tests/.mocharc.json b/npm/create-cypress-tests/.mocharc.json deleted file mode 100644 index 05d782fced5a..000000000000 --- a/npm/create-cypress-tests/.mocharc.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "watch-ignore": [ - "node_modules" - ], - "require": "ts-node/register", - "exit": true -} diff --git a/npm/create-cypress-tests/.npmignore b/npm/create-cypress-tests/.npmignore deleted file mode 100644 index c9cfa44194a1..000000000000 --- a/npm/create-cypress-tests/.npmignore +++ /dev/null @@ -1,4 +0,0 @@ -./src/ -./initial-template/ -scripts/ -__snapshots__/ \ No newline at end of file diff --git a/npm/create-cypress-tests/README.md b/npm/create-cypress-tests/README.md deleted file mode 100644 index a845dd0b82a1..000000000000 --- a/npm/create-cypress-tests/README.md +++ /dev/null @@ -1,52 +0,0 @@ -# Create Cypress Tests - -Installs and injects all the required configuration to run cypress tests. - -## Quick overview - -``` -cd my-app -npx create-cypress-test -npx cypress open -``` - -![demo](./demo.gif) - -## Package manager - -This wizard will automatically determine which package do you use. If `yarn` available as global dependency it will use yarn to install dependencies and create lock file. - -If you need to use `npm` over `yarn` you can do the following - -``` -npx create-cypress-tests --use-npm -``` - -By the way you can use yarn to run the installation wizard ๐Ÿ˜‰ - -``` -yarn create cypress tests -``` - -## Typescript - -This package will also automatically determine if typescript if available in this project and inject the required typescript configuration for cypress. If you are starting a new project and want to create typescript configuration, please do the following: - -``` -npm init -npm install typescript -npx create-cypress-tests -``` - -## Configuration - -Here is a list of available configuration options: - -`--use-npm` โ€“ย use npm if yarn available -`--ignore-typescript` โ€“ will not create typescript configuration if available -`--ignore-examples` โ€“ย will create a 1 empty spec file (`cypress/integration/spec.js`) to start with -`--component-tests`ย โ€“ will not ask should setup component testing or not - -## License - -The project is licensed under the terms of [MIT license](../../LICENSE) \ No newline at end of file diff --git a/npm/create-cypress-tests/__snapshots__/babel.test.ts.js b/npm/create-cypress-tests/__snapshots__/babel.test.ts.js deleted file mode 100644 index 5e5dc1658279..000000000000 --- a/npm/create-cypress-tests/__snapshots__/babel.test.ts.js +++ /dev/null @@ -1,10 +0,0 @@ -exports['babel installation template correctly generates plugins config 1'] = ` -const preprocessor = require('@cypress/react/plugins/babel'); - -const something = require("something"); - -module.exports = (on, config) => { - preprocessor(on, config); - return config; // IMPORTANT to return the config object -}; -` diff --git a/npm/create-cypress-tests/__snapshots__/init-component-testing.test.ts.js b/npm/create-cypress-tests/__snapshots__/init-component-testing.test.ts.js deleted file mode 100644 index bc623f51e593..000000000000 --- a/npm/create-cypress-tests/__snapshots__/init-component-testing.test.ts.js +++ /dev/null @@ -1,50 +0,0 @@ -exports['Injects guessed next.js template cypress.json'] = ` -const preprocessor = require("@cypress/react/plugins/next"); - -module.exports = (on, config) => { - preprocessor(on, config); - return config; // IMPORTANT to return the config object -}; - -` - -exports['Injects guessed next.js template plugins/index.js'] = ` -const preprocessor = require("@cypress/react/plugins/next"); - -module.exports = (on, config) => { - preprocessor(on, config); - return config; // IMPORTANT to return the config object -}; - -` - -exports['Injects guessed next.js template support/index.js'] = ` -import "@cypress/react/support"; - -` - -exports['Injected overridden webpack template cypress.json'] = ` -const preprocessor = require("@cypress/react/plugins/react-scripts"); - -module.exports = (on, config) => { - preprocessor(on, config); - return config; // IMPORTANT to return the config object -}; - -` - -exports['Injected overridden webpack template plugins/index.js'] = ` -const preprocessor = require("@cypress/react/plugins/react-scripts"); - -module.exports = (on, config) => { - preprocessor(on, config); - return config; // IMPORTANT to return the config object -}; - -` - -exports['Injected overridden webpack template support/index.js'] = ` -import "./commands.js"; -import "@cypress/react/support"; - -` diff --git a/npm/create-cypress-tests/__snapshots__/next.test.ts.js b/npm/create-cypress-tests/__snapshots__/next.test.ts.js deleted file mode 100644 index 5fffc9059960..000000000000 --- a/npm/create-cypress-tests/__snapshots__/next.test.ts.js +++ /dev/null @@ -1,10 +0,0 @@ -exports['next.js install template correctly generates plugins config 1'] = ` -const preprocessor = require('@cypress/react/plugins/next'); - -const something = require("something"); - -module.exports = (on, config) => { - preprocessor(on, config); - return config; // IMPORTANT to return the config object -}; -` diff --git a/npm/create-cypress-tests/__snapshots__/react-scripts.test.ts.js b/npm/create-cypress-tests/__snapshots__/react-scripts.test.ts.js deleted file mode 100644 index 53f5b90ea4ae..000000000000 --- a/npm/create-cypress-tests/__snapshots__/react-scripts.test.ts.js +++ /dev/null @@ -1,10 +0,0 @@ -exports['create-react-app install template correctly generates plugins config 1'] = ` -const preprocessor = require('@cypress/react/plugins/react-scripts'); - -const something = require("something"); - -module.exports = (on, config) => { - preprocessor(on, config); - return config; // IMPORTANT to return the config object -}; -` diff --git a/npm/create-cypress-tests/__snapshots__/reactWebpackFile.test.ts.js b/npm/create-cypress-tests/__snapshots__/reactWebpackFile.test.ts.js deleted file mode 100644 index 314d0ac6f470..000000000000 --- a/npm/create-cypress-tests/__snapshots__/reactWebpackFile.test.ts.js +++ /dev/null @@ -1,24 +0,0 @@ -exports['webpack-file install template correctly generates plugins config when webpack config path is missing 1'] = ` -const preprocessor = require("@cypress/react/plugins/load-webpack"); - -const something = require("something"); - -module.exports = (on, config) => { - // TODO replace with valid webpack config path - config.env.webpackFilename = './webpack.config.js'; - preprocessor(on, config); - return config; // IMPORTANT to return the config object -}; -` - -exports['webpack-file install template correctly generates plugins config when webpack config path is provided 1'] = ` -const preprocessor = require("@cypress/react/plugins/load-webpack"); - -const something = require("something"); - -module.exports = (on, config) => { - config.env.webpackFilename = 'config/webpack.config.js'; - preprocessor(on, config); - return config; // IMPORTANT to return the config object -}; -` diff --git a/npm/create-cypress-tests/__snapshots__/rollup.test.ts.js b/npm/create-cypress-tests/__snapshots__/rollup.test.ts.js deleted file mode 100644 index 3e28e760ff9b..000000000000 --- a/npm/create-cypress-tests/__snapshots__/rollup.test.ts.js +++ /dev/null @@ -1,32 +0,0 @@ -exports['rollup-file install template correctly generates plugins config when webpack config path is missing 1'] = ` -const rollupPreprocessor = require("@bahmutov/cy-rollup"); - -const something = require("something"); - -module.exports = (on, config) => { - on('file:preprocessor', rollupPreprocessor({ - // TODO replace with valid rollup config path - configFile: 'rollup.config.js' - })); - - require('@cypress/code-coverage/task')(on, config); - - return config; // IMPORTANT to return the config object -}; -` - -exports['rollup-file install template correctly generates plugins config when webpack config path is provided 1'] = ` -const rollupPreprocessor = require("@bahmutov/cy-rollup"); - -const something = require("something"); - -module.exports = (on, config) => { - on('file:preprocessor', rollupPreprocessor({ - configFile: 'config/rollup.config.js' - })); - - require('@cypress/code-coverage/task')(on, config); - - return config; // IMPORTANT to return the config object -}; -` diff --git a/npm/create-cypress-tests/__snapshots__/vueCli.test.ts.js b/npm/create-cypress-tests/__snapshots__/vueCli.test.ts.js deleted file mode 100644 index ec7c70acef0f..000000000000 --- a/npm/create-cypress-tests/__snapshots__/vueCli.test.ts.js +++ /dev/null @@ -1,11 +0,0 @@ -exports['vue webpack-file install template correctly generates plugins for vue-cli-service 1'] = ` -const preprocessor = require("@cypress/vue/dist/plugins/webpack"); - -const something = require("something"); - -module.exports = (on, config) => { - preprocessor(on, config); // IMPORTANT return the config object - - return config; -}; -` diff --git a/npm/create-cypress-tests/__snapshots__/vueWebpackFile.test.ts.js b/npm/create-cypress-tests/__snapshots__/vueWebpackFile.test.ts.js deleted file mode 100644 index 373b8e8975f6..000000000000 --- a/npm/create-cypress-tests/__snapshots__/vueWebpackFile.test.ts.js +++ /dev/null @@ -1,24 +0,0 @@ -exports['vue webpack-file install template correctly generates plugins config when webpack config path is missing 1'] = ` -const { - onFilePreprocessor -} = require('@cypress/vue/dist/preprocessor/webpack'); - -const something = require("something"); - -module.exports = (on, config) => { - // TODO replace with valid webpack config path - on('file:preprocessor', onFilePreprocessor('./webpack.config.js')); -}; -` - -exports['vue webpack-file install template correctly generates plugins config when webpack config path is provided 1'] = ` -const { - onFilePreprocessor -} = require('@cypress/vue/dist/preprocessor/webpack'); - -const something = require("something"); - -module.exports = (on, config) => { - on('file:preprocessor', onFilePreprocessor('build/webpack.config.js')); -}; -` diff --git a/npm/create-cypress-tests/__snapshots__/webpackOptions.test.ts.js b/npm/create-cypress-tests/__snapshots__/webpackOptions.test.ts.js deleted file mode 100644 index 352d39aff258..000000000000 --- a/npm/create-cypress-tests/__snapshots__/webpackOptions.test.ts.js +++ /dev/null @@ -1,29 +0,0 @@ -exports['webpack-options template correctly generates plugins config 1'] = ` -const webpackPreprocessor = require("@cypress/webpack-preprocessor"); - -const something = require("something"); - -module.exports = (on, config) => { - const opts = webpackPreprocessor.defaultOptions; - const babelLoader = opts.webpackOptions.module.rules[0].use[0]; // add React preset to be able to transpile JSX - - babelLoader.options.presets.push(require.resolve('@babel/preset-react')); // We can also push Babel istanbul plugin to instrument the code on the fly - // and get code coverage reports from component tests (optional) - - if (!babelLoader.options.plugins) { - babelLoader.options.plugins = []; - } - - babelLoader.options.plugins.push(require.resolve('babel-plugin-istanbul')); // in order to mock named imports, need to include a plugin - - babelLoader.options.plugins.push([require.resolve('@babel/plugin-transform-modules-commonjs'), { - loose: true - }]); // add code coverage plugin - - require('@cypress/code-coverage/task')(on, config); - - on('file:preprocessor', webpackPreprocessor(opts)); // if adding code coverage, important to return updated config - - return config; -}; -` diff --git a/npm/create-cypress-tests/demo.gif b/npm/create-cypress-tests/demo.gif deleted file mode 100644 index 344fc47d3faa..000000000000 Binary files a/npm/create-cypress-tests/demo.gif and /dev/null differ diff --git a/npm/create-cypress-tests/package.json b/npm/create-cypress-tests/package.json deleted file mode 100644 index e2cd65c174d6..000000000000 --- a/npm/create-cypress-tests/package.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "name": "create-cypress-tests", - "version": "0.0.0-development", - "description": "Cypress smart installation wizard", - "private": false, - "main": "index.js", - "scripts": { - "build": "yarn prepare-example && tsc -p ./tsconfig.json && chmod +x dist/src/index.js && node scripts/example copy-to ./dist/initial-template", - "prepare-example": "node scripts/example copy-to ./initial-template", - "test": "cross-env TS_NODE_PROJECT=./tsconfig.test.json mocha --config .mocharc.json './src/**/*.test.ts'", - "test:watch": "yarn test -w" - }, - "dependencies": { - "@babel/core": "^7.5.4", - "@babel/plugin-transform-typescript": "^7.2.0", - "@babel/template": "^7.5.4", - "@babel/types": "^7.5.0", - "bluebird": "^3.7.2", - "chalk": "4.1.0", - "cli-highlight": "2.1.4", - "commander": "6.1.0", - "find-up": "5.0.0", - "fs-extra": "^9.0.1", - "glob": "^7.1.6", - "inquirer": "7.3.3", - "ora": "^5.1.0" - }, - "devDependencies": { - "@types/babel__core": "^7.1.2", - "@types/inquirer": "7.3.1", - "@types/mock-fs": "4.10.0", - "@types/node": "9.6.49", - "@types/ora": "^3.2.0", - "mocha": "7.1.1", - "mock-fs": "4.13.0", - "typescript": "4.0.3" - }, - "bin": { - "create-cypress-tests": "dist/src/index.js" - }, - "license": "MIT", - "repository": "https://github.com/cypress-io/cypress.git", - "author": "Cypress.io team" -} diff --git a/npm/create-cypress-tests/scripts/example.js b/npm/create-cypress-tests/scripts/example.js deleted file mode 100644 index 23fd021fea45..000000000000 --- a/npm/create-cypress-tests/scripts/example.js +++ /dev/null @@ -1,19 +0,0 @@ -const fs = require('fs-extra') -const chalk = require('chalk') -const path = require('path') -const program = require('commander') - -program -.command('copy-to [destination]') -.description('copy cypress/packages/example into destination') -.action(async (destination) => { - const exampleFolder = path.resolve(__dirname, '..', '..', '..', 'packages', 'example') - const destinationPath = path.resolve(process.cwd(), destination) - - await fs.remove(destinationPath) - await fs.copy(exampleFolder, destinationPath, { recursive: true }) - - console.log(`โœ… Example was successfully created at ${chalk.cyan(destination)}`) -}) - -program.parse(process.argv) diff --git a/npm/create-cypress-tests/src/component-testing/babel/babelTransform.test.ts b/npm/create-cypress-tests/src/component-testing/babel/babelTransform.test.ts deleted file mode 100644 index 78c6e5c93c2a..000000000000 --- a/npm/create-cypress-tests/src/component-testing/babel/babelTransform.test.ts +++ /dev/null @@ -1,85 +0,0 @@ -import * as babel from '@babel/core' -import { expect } from 'chai' -import { createSupportBabelPlugin, createTransformPluginsFileBabelPlugin } from './babelTransform' - -describe('babel transform utils', () => { - context('support babel template', () => { - it('injects import after the last import in the file', () => { - const plugin = createSupportBabelPlugin('import "@cypress/react"') - - const output = babel.transformSync([ - 'import "./commands.js"', - ].join('\n'), { - plugins: [plugin], - })?.code - - expect(output).to.equal([ - 'import "./commands.js";', - 'import "@cypress/react";', - ].join('\n')) - }) - - it('injects import after the last import if a lot of imports and code inside', () => { - const plugin = createSupportBabelPlugin('import "@cypress/react"') - - const output = babel.transformSync([ - 'import "./commands.js";', - 'import "./commands4.js";', - 'import "./commands3.js";', - 'import "./commands2.js";', - '', - 'function hello() {', - ' console.log("world");', - '}', - ].join('\n'), { - plugins: [plugin], - })?.code - - expect(output).to.equal([ - 'import "./commands.js";', - 'import "./commands4.js";', - 'import "./commands3.js";', - 'import "./commands2.js";', - 'import "@cypress/react";', - '', - 'function hello() {', - ' console.log("world");', - '}', - ].join('\n')) - }) - - it('adds import as 1st line if no imports or require found', () => { - const plugin = createSupportBabelPlugin('import "@cypress/react"') - - const output = babel.transformSync('', { plugins: [plugin] })?.code - - expect(output).to.equal('import "@cypress/react";') - }) - }) - - context('Plugins config babel plugin', () => { - it('injects code into the plugins file based on ast', () => { - const plugin = createTransformPluginsFileBabelPlugin({ - Require: babel.template.ast('require("something")'), - ModuleExportsBody: babel.template.ast('yey()'), - }) - - const output = babel.transformSync([ - 'module.exports = (on, config) => {', - 'on("do")', - '}', - ].join('\n'), { - plugins: [plugin], - })?.code - - expect(output).to.equal([ - 'require("something");', - '', - 'module.exports = (on, config) => {', - ' on("do");', - ' yey();', - '};', - ].join(`\n`)) - }) - }) -}) diff --git a/npm/create-cypress-tests/src/component-testing/babel/babelTransform.ts b/npm/create-cypress-tests/src/component-testing/babel/babelTransform.ts deleted file mode 100644 index 56be68ce83ea..000000000000 --- a/npm/create-cypress-tests/src/component-testing/babel/babelTransform.ts +++ /dev/null @@ -1,147 +0,0 @@ -import path from 'path' -import * as fs from 'fs-extra' -import * as babel from '@babel/core' -import * as babelTypes from '@babel/types' - -export type PluginsConfigAst = Record<'Require' | 'ModuleExportsBody', ReturnType> - -function tryRequirePrettier () { - try { - return require('prettier') - } catch (e) { - return null - } -} - -async function transformFileViaPlugin (filePath: string, babelPlugin: babel.PluginObj) { - try { - const initialCode = await fs.readFile(filePath, { encoding: 'utf-8' }) - - const updatedResult = await babel.transformAsync(initialCode, { - filename: path.basename(filePath), - filenameRelative: path.relative(process.cwd(), filePath), - plugins: [babelPlugin], - presets: [], - }) - - if (!updatedResult) { - return false - } - - let finalCode = updatedResult.code - - if (finalCode === initialCode) { - return false - } - - const maybePrettier = tryRequirePrettier() - - if (maybePrettier && maybePrettier.format) { - finalCode = maybePrettier.format(finalCode, { parser: 'babel' }) - } - - await fs.writeFile(filePath, finalCode) - - return true - } catch (e) { - return false - } -} - -export function createTransformPluginsFileBabelPlugin (ast: PluginsConfigAst): babel.PluginObj { - return { - visitor: { - Program: (path) => { - path.unshiftContainer('body', ast.Require) - }, - Function: (path) => { - if (!babelTypes.isAssignmentExpression(path.parent)) { - return - } - - const assignment = path.parent.left - - const isModuleExports = - babelTypes.isMemberExpression(assignment) - && babelTypes.isIdentifier(assignment.object) - && assignment.object.name === 'module' - && babelTypes.isIdentifier(assignment.property) - && assignment.property.name === 'exports' - - if (isModuleExports && babelTypes.isFunction(path.parent.right)) { - const paramsLength = path.parent.right.params.length - - if (paramsLength === 0) { - path.parent.right.params.push(babelTypes.identifier('on')) - path.parent.right.params.push(babelTypes.identifier('config')) - } - - if (paramsLength === 1) { - path.parent.right.params.push(babelTypes.identifier('config')) - } - - path.get('body').pushContainer('body' as never, ast.ModuleExportsBody) - } - }, - }, - } -} - -export async function injectPluginsCode (pluginsFilePath: string, ast: PluginsConfigAst) { - return transformFileViaPlugin(pluginsFilePath, createTransformPluginsFileBabelPlugin(ast)) -} - -export async function getPluginsSourceExample (ast: PluginsConfigAst) { - const exampleCode = [ - 'module.exports = (on, config) => {', - '', - '}', - ].join('\n') - - try { - const babelResult = await babel.transformAsync(exampleCode, { - filename: 'nothing.js', - plugins: [createTransformPluginsFileBabelPlugin(ast)], - presets: [], - }) - - if (!babelResult?.code) { - throw new Error() - } - - return babelResult.code - } catch (e) { - throw new Error('Can not generate code example for plugins file because of unhandled error. Please update the plugins file manually.') - } -} - -export function createSupportBabelPlugin (importCode: string): babel.PluginObj { - const template = babel.template.ast(importCode) - - const plugin: babel.PluginObj<{ - root: babel.NodePath - lastImport: babel.NodePath |null - }> = { - visitor: { - Program (path) { - this.root = path - }, - ImportDeclaration (path) { - this.lastImport = path - }, - }, - post () { - if (this.lastImport) { - this.lastImport.insertAfter(template) - } else if (this.root) { - this.root.unshiftContainer('body', template) - } - }, - } - - return plugin -} - -export async function injectImportSupportCode (supportFilePath: string, importCode: string) { - return transformFileViaPlugin(supportFilePath, createSupportBabelPlugin(importCode)) -} diff --git a/npm/create-cypress-tests/src/component-testing/init-component-testing.test.ts b/npm/create-cypress-tests/src/component-testing/init-component-testing.test.ts deleted file mode 100644 index 1353623145f4..000000000000 --- a/npm/create-cypress-tests/src/component-testing/init-component-testing.test.ts +++ /dev/null @@ -1,266 +0,0 @@ -import path from 'path' -import fs from 'fs-extra' -import snapshot from 'snap-shot-it' -import { expect, use } from 'chai' -import sinon, { SinonStub, SinonSpy } from 'sinon' -import chalk from 'chalk' -import mockFs from 'mock-fs' -import { initComponentTesting } from './init-component-testing' -import inquirer from 'inquirer' -import sinonChai from 'sinon-chai' -import childProcess from 'child_process' -import { someOfSpyCallsIncludes } from '../test-utils' - -use(sinonChai) - -describe('init component tests script', () => { - let promptSpy: SinonStub | null = null - let logSpy: SinonSpy | null = null - let processExitStub: SinonStub | null = null - let execStub: SinonStub | null = null - - const e2eTestOutputPath = path.resolve(__dirname, '..', 'test-output') - const cypressConfigPath = path.join(e2eTestOutputPath, 'cypress.json') - - beforeEach(async () => { - logSpy = sinon.spy(global.console, 'log') - // @ts-ignores - execStub = sinon.stub(childProcess, 'exec').callsFake((command, callback) => callback()) - processExitStub = sinon.stub(process, 'exit').callsFake(() => { - throw new Error(`${chalk.red('process.exit')} should not be called`) - }) - - await fs.remove(e2eTestOutputPath) - await fs.mkdir(e2eTestOutputPath) - }) - - afterEach(() => { - mockFs.restore() - logSpy?.restore() - promptSpy?.restore() - processExitStub?.restore() - execStub?.restore() - }) - - function createTempFiles (tempFiles: Record) { - Object.entries(tempFiles).forEach(([fileName, content]) => { - fs.outputFileSync( - path.join(e2eTestOutputPath, fileName), - content, - ) - }) - } - - function snapshotGeneratedFiles (name: string) { - snapshot( - `${name} cypress.json`, - fs.readFileSync( - path.join(e2eTestOutputPath, 'cypress', 'plugins', 'index.js'), - { encoding: 'utf-8' }, - ), - ) - - snapshot( - `${name} plugins/index.js`, - fs.readFileSync( - path.join(e2eTestOutputPath, 'cypress', 'plugins', 'index.js'), - { encoding: 'utf-8' }, - ), - ) - - snapshot( - `${name} support/index.js`, - fs.readFileSync( - path.join(e2eTestOutputPath, 'cypress', 'support', 'index.js'), - { encoding: 'utf-8' }, - ), - ) - } - - it('determines more presumable configuration to suggest', async () => { - createTempFiles({ - '/cypress.json': '{}', - '/cypress/support/index.js': '', - '/cypress/plugins/index.js': 'module.exports = (on, config) => {}', - // For next.js user will have babel config, but we want to suggest to use the closest config for the application code - '/babel.config.js': 'module.exports = { }', - '/package.json': JSON.stringify({ dependencies: { react: '^17.x', next: '^9.2.0' } }), - }) - - promptSpy = sinon.stub(inquirer, 'prompt').returns(Promise.resolve({ - chosenTemplateName: 'next.js', - componentFolder: 'src', - }) as any) - - await initComponentTesting({ config: {}, cypressConfigPath, useYarn: true }) - - const [{ choices }] = (inquirer.prompt as any).args[0][0] - - expect(choices[0]).to.equal('next.js') - snapshotGeneratedFiles('Injects guessed next.js template') - }) - - it('automatically suggests to the user which config to use', async () => { - createTempFiles({ - '/cypress.json': '{}', - '/cypress/support/index.js': 'import "./commands.js";', - '/cypress/plugins/index.js': 'module.exports = () => {}', - '/package.json': JSON.stringify({ - dependencies: { - react: '^16.10.0', - }, - }), - '/webpack.config.js': 'module.exports = { }', - }) - - promptSpy = sinon.stub(inquirer, 'prompt').returns(Promise.resolve({ - chosenTemplateName: 'create-react-app', - componentFolder: 'cypress/component', - }) as any) - - await initComponentTesting({ config: {}, cypressConfigPath, useYarn: true }) - const [{ choices, message }] = (inquirer.prompt as any).args[0][0] - - expect(choices[0]).to.equal('webpack') - expect(message).to.contain( - `Press ${chalk.inverse(' Enter ')} to continue with ${chalk.green( - 'webpack', - )} configuration`, - ) - - snapshotGeneratedFiles('Injected overridden webpack template') - }) - - it('Asks for preferred bundling tool if can not determine the right one', async () => { - createTempFiles({ - '/cypress.json': '{}', - '/webpack.config.js': 'module.exports = { }', - '/package.json': JSON.stringify({ dependencies: { } }), - }) - - promptSpy = sinon.stub(inquirer, 'prompt') - .onCall(0) - .returns(Promise.resolve({ - framework: 'vue', - }) as any) - .onCall(1) - .returns(Promise.resolve({ - chosenTemplateName: 'webpack', - componentFolder: 'src', - }) as any) - - await initComponentTesting({ config: {}, cypressConfigPath, useYarn: true }) - - expect( - someOfSpyCallsIncludes(global.console.log, 'We were unable to automatically determine your framework ๐Ÿ˜ฟ'), - ).to.be.true - }) - - it('Asks for framework if more than 1 option was auto detected', async () => { - createTempFiles({ - '/cypress.json': '{}', - '/webpack.config.js': 'module.exports = { }', - '/package.json': JSON.stringify({ dependencies: { react: '*', vue: '*' } }), - }) - - promptSpy = sinon.stub(inquirer, 'prompt') - .onCall(0) - .returns(Promise.resolve({ - framework: 'vue', - }) as any) - .onCall(1) - .returns(Promise.resolve({ - chosenTemplateName: 'webpack', - componentFolder: 'src', - }) as any) - - await initComponentTesting({ config: {}, cypressConfigPath, useYarn: true }) - - expect( - someOfSpyCallsIncludes(global.console.log, `It looks like all these frameworks: ${chalk.yellow('react, vue')} are available from this directory.`), - ).to.be.true - }) - - it('installs the right adapter', () => { - - }) - - it('suggest the right instruction based on user template choice', async () => { - createTempFiles({ - '/package.json': JSON.stringify({ - dependencies: { - react: '^16.0.0', - }, - }), - '/cypress.json': '{}', - }) - - promptSpy = sinon.stub(inquirer, 'prompt').returns(Promise.resolve({ - chosenTemplateName: 'create-react-app', - componentFolder: 'src', - }) as any) - - await initComponentTesting({ config: {}, cypressConfigPath, useYarn: true }) - expect( - someOfSpyCallsIncludes( - global.console.log, - 'https://github.com/cypress-io/cypress/tree/develop/npm/react/examples/react-scripts', - ), - ).to.be.true - }) - - it('suggests right docs example and cypress.json config based on the `componentFolder` answer', async () => { - createTempFiles({ - '/cypress.json': '{}', - '/package.json': JSON.stringify({ - dependencies: { - react: '^16.0.0', - }, - }), - }) - - sinon.stub(inquirer, 'prompt').returns(Promise.resolve({ - chosenTemplateName: 'create-react-app', - componentFolder: 'cypress/component', - }) as any) - - await initComponentTesting({ config: {}, cypressConfigPath, useYarn: true }) - - const injectedCode = fs.readFileSync(path.join(e2eTestOutputPath, 'cypress.json'), { encoding: 'utf-8' }) - - expect(injectedCode).to.equal(JSON.stringify( - { - experimentalComponentTesting: true, - componentFolder: 'cypress/component', - testFiles: '**/*.spec.{js,ts,jsx,tsx}', - }, - null, - 2, - )) - }) - - it('Shows help message if cypress files are not created', async () => { - createTempFiles({ - '/cypress.json': '{}', - '/package.json': JSON.stringify({ - dependencies: { - react: '^16.0.0', - }, - }), - }) - - sinon.stub(inquirer, 'prompt').returns(Promise.resolve({ - chosenTemplateName: 'create-react-app', - componentFolder: 'cypress/component', - }) as any) - - await initComponentTesting({ config: {}, cypressConfigPath, useYarn: true }) - - expect( - someOfSpyCallsIncludes( - global.console.log, - 'was not updated automatically. Please add the following config manually:', - ), - ).to.be.true - }) -}) diff --git a/npm/create-cypress-tests/src/component-testing/init-component-testing.ts b/npm/create-cypress-tests/src/component-testing/init-component-testing.ts deleted file mode 100644 index a6a7dc86c486..000000000000 --- a/npm/create-cypress-tests/src/component-testing/init-component-testing.ts +++ /dev/null @@ -1,216 +0,0 @@ -import fs from 'fs-extra' -import path from 'path' -import chalk from 'chalk' -import inquirer from 'inquirer' -import highlight from 'cli-highlight' -import { Template } from './templates/Template' -import { guessTemplate } from './templates/guessTemplate' -import { installFrameworkAdapter } from './installFrameworkAdapter' -import { injectImportSupportCode, injectPluginsCode, getPluginsSourceExample } from './babel/babelTransform' - -async function injectOrShowConfigCode (injectFn: () => Promise, { - code, - filePath, - fallbackFileMessage, - language, -}: { - code: string - filePath: string - language: string - fallbackFileMessage: string -}) { - const fileExists = fs.existsSync(filePath) - const readableFilePath = fileExists ? path.relative(process.cwd(), filePath) : fallbackFileMessage - - const printCode = () => { - console.log() - console.log(highlight(code, { language })) - console.log() - } - - const printSuccess = () => { - console.log(`โœ… ${chalk.bold.green(readableFilePath)} was updated with the following config:`) - printCode() - } - - const printFailure = () => { - console.log(`โŒ ${chalk.bold.red(readableFilePath)} was not updated automatically. Please add the following config manually: `) - printCode() - } - - if (!fileExists) { - printFailure() - - return - } - - // something get completely wrong when using babel or something. Print error message. - const injected = await injectFn().catch(() => false) - - injected ? printSuccess() : printFailure() -} - -async function injectAndShowCypressJsonConfig ( - cypressJsonPath: string, - componentFolder: string, -) { - const configToInject = { - experimentalComponentTesting: true, - componentFolder, - testFiles: '**/*.spec.{js,ts,jsx,tsx}', - } - - async function autoInjectCypressJson () { - const currentConfig = JSON.parse(await fs.readFile(cypressJsonPath, { encoding: 'utf-8' })) - - await fs.writeFile(cypressJsonPath, JSON.stringify({ - ...currentConfig, - ...configToInject, - }, null, 2)) - - return true - } - - await injectOrShowConfigCode(autoInjectCypressJson, { - code: JSON.stringify(configToInject, null, 2), - language: 'js', - filePath: cypressJsonPath, - fallbackFileMessage: 'cypress.json config file', - }) -} - -async function injectAndShowSupportConfig (supportFilePath: string, framework: string) { - const importCode = framework === 'vue' - ? `import '@cypress/vue/dist/support'` // todo change vue bundle to output the right declaration - : `import \'@cypress/${framework}/support\'` - - await injectOrShowConfigCode(() => injectImportSupportCode(supportFilePath, importCode), { - code: importCode, - language: 'js', - filePath: supportFilePath, - fallbackFileMessage: 'support file (https://docs.cypress.io/guides/core-concepts/writing-and-organizing-tests.html#Support-file)', - }) -} - -async function injectAndShowPluginConfig (template: Template, { - templatePayload, - pluginsFilePath, - cypressProjectRoot, -}: { - templatePayload: T | null - pluginsFilePath: string - cypressProjectRoot: string -}) { - const ast = template.getPluginsCodeAst(templatePayload, { cypressProjectRoot }) - - await injectOrShowConfigCode(() => injectPluginsCode(pluginsFilePath, ast), { - code: await getPluginsSourceExample(ast), - language: 'js', - filePath: pluginsFilePath, - fallbackFileMessage: 'plugins file (https://docs.cypress.io/guides/core-concepts/writing-and-organizing-tests.html#Plugin-files)', - }) -} - -type InitComponentTestingOptions = { - config: Record - cypressConfigPath: string - useYarn: boolean -} - -export async function initComponentTesting ({ config, useYarn, cypressConfigPath }: InitComponentTestingOptions) { - const cypressProjectRoot = path.resolve(cypressConfigPath, '..') - - const framework = await installFrameworkAdapter(cypressProjectRoot, { useYarn }) - const { - possibleTemplates, - defaultTemplate, - defaultTemplateName, - templatePayload, - } = await guessTemplate(framework, cypressProjectRoot) - - const pluginsFilePath = path.resolve( - cypressProjectRoot, - config.pluginsFile ?? './cypress/plugins/index.js', - ) - - const supportFilePath = path.resolve( - cypressProjectRoot, - config.supportFile ?? './cypress/support/index.js', - ) - - const templateChoices = Object.keys(possibleTemplates).sort((key) => { - return key === defaultTemplateName ? -1 : 0 - }) - - const { - chosenTemplateName, - componentFolder, - }: Record = await inquirer.prompt([ - { - type: 'list', - name: 'chosenTemplateName', - choices: templateChoices, - default: defaultTemplate ? 0 : undefined, - message: defaultTemplate?.message - ? `${defaultTemplate?.message}\n\n Press ${chalk.inverse( - ' Enter ', - )} to continue with ${chalk.green( - defaultTemplateName, - )} configuration or select another template from the list:` - : 'We were not able to automatically determine which framework or bundling tool you are using. Please choose one from the list:', - }, - { - type: 'input', - name: 'componentFolder', - filter: (input) => input.trim(), - validate: (input) => { - return input === '' || !/^[a-zA-Z].*/.test(input) - ? `Directory "${input}" is invalid` - : true - }, - message: 'Which folder would you like to use for your component tests?', - default: (answers: { chosenTemplateName: keyof typeof possibleTemplates }) => { - return possibleTemplates[answers.chosenTemplateName].recommendedComponentFolder - }, - }, - ]) - - const chosenTemplate = possibleTemplates[chosenTemplateName] as Template - - console.log() - console.log(`Here are instructions of how to get started with component testing for ${chalk.cyan(chosenTemplateName)}:`) - console.log() - - await injectAndShowCypressJsonConfig(cypressConfigPath, componentFolder) - await injectAndShowSupportConfig(supportFilePath, framework) - await injectAndShowPluginConfig(chosenTemplate, { - templatePayload, - pluginsFilePath, - cypressProjectRoot, - }) - - if (chosenTemplate.printHelper) { - chosenTemplate.printHelper() - } - - console.log( - `Find examples of component tests for ${chalk.green( - chosenTemplateName, - )} in ${chalk.underline(chosenTemplate.getExampleUrl({ componentFolder }))}.`, - ) - - if (framework === 'react') { - console.log() - - console.log( - `Docs for different recipes of bundling tools: ${chalk.bold.underline( - 'https://github.com/cypress-io/cypress/tree/develop/npm/react/docs/recipes.md', - )}`, - ) - } - - // render delimiter - console.log() - console.log(new Array(process.stdout.columns).fill('โ•').join('')) - console.log() -} diff --git a/npm/create-cypress-tests/src/component-testing/installFrameworkAdapter.ts b/npm/create-cypress-tests/src/component-testing/installFrameworkAdapter.ts deleted file mode 100644 index c08f0074bc50..000000000000 --- a/npm/create-cypress-tests/src/component-testing/installFrameworkAdapter.ts +++ /dev/null @@ -1,56 +0,0 @@ -import chalk from 'chalk' -import inquirer from 'inquirer' -import { scanFSForAvailableDependency } from '../findPackageJson' -import { installDependency } from '../utils' - -async function guessOrAskForFramework (cwd: string): Promise<'react' | 'vue'> { - // please sort this alphabetically - const frameworks = { - react: () => scanFSForAvailableDependency(cwd, ['react', 'react-dom']), - vue: () => scanFSForAvailableDependency(cwd, ['vue']), - } - - const guesses = Object.keys(frameworks).filter((framework) => { - return frameworks[framework as keyof typeof frameworks]() - }) as Array<'react' | 'vue'> - - // found 1 precise guess. Continue - if (guesses.length === 1) { - const framework = guesses[0] - - console.log(`\nThis project is using ${chalk.bold.cyan(framework)}. Let's install the right adapter:`) - - return framework - } - - if (guesses.length === 0) { - console.log(`We were unable to automatically determine your framework ๐Ÿ˜ฟ. ${chalk.grey('Make sure to run this command from the directory where your components located in order to make smart detection works. Or continue with manual setup:')}`) - } - - if (guesses.length > 0) { - console.log(`It looks like all these frameworks: ${chalk.yellow(guesses.join(', '))} are available from this directory. ${chalk.grey('Make sure to run this command from the directory where your components located in order to make smart detection works. Or continue with manual setup:')}`) - } - - const { framework } = await inquirer.prompt([ - { - type: 'list', - name: 'framework', - choices: Object.keys(frameworks), - message: `Which framework do you use?`, - }, - ]) - - return framework -} - -type InstallAdapterOptions = { - useYarn: boolean -} - -export async function installFrameworkAdapter (cwd: string, options: InstallAdapterOptions) { - const framework = await guessOrAskForFramework(cwd) - - await installDependency(`@cypress/${framework}`, options) - - return framework -} diff --git a/npm/create-cypress-tests/src/component-testing/templates/Template.ts b/npm/create-cypress-tests/src/component-testing/templates/Template.ts deleted file mode 100644 index 426b156bc544..000000000000 --- a/npm/create-cypress-tests/src/component-testing/templates/Template.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { PluginsConfigAst } from '../babel/babelTransform' - -export interface Template { - message: string - getExampleUrl: ({ componentFolder }: { componentFolder: string }) => string - recommendedComponentFolder: string - test(rootPath: string): { success: boolean, payload?: T } - getPluginsCodeAst: ( - payload: T | null, - options: { cypressProjectRoot: string }, - ) => PluginsConfigAst - printHelper?: () => void -} diff --git a/npm/create-cypress-tests/src/component-testing/templates/guessTemplate.ts b/npm/create-cypress-tests/src/component-testing/templates/guessTemplate.ts deleted file mode 100644 index dffffe4e0e7f..000000000000 --- a/npm/create-cypress-tests/src/component-testing/templates/guessTemplate.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { Template } from './Template' -import { reactTemplates } from './react' -import { vueTemplates } from './vue' - -const allTemplates = { - react: reactTemplates, - vue: vueTemplates, -} - -export async function guessTemplate (framework: keyof typeof allTemplates, cwd: string) { - const templates = allTemplates[framework] - - for (const [name, template] of Object.entries(templates)) { - const typedTemplate = template as Template - const { success, payload } = typedTemplate.test(cwd) - - if (success) { - return { - defaultTemplate: typedTemplate, - defaultTemplateName: name, - templatePayload: payload ?? null, - possibleTemplates: templates, - } - } - } - - return { - templatePayload: null, - defaultTemplate: null, - defaultTemplateName: null, - possibleTemplates: templates, - } -} diff --git a/npm/create-cypress-tests/src/component-testing/templates/react/babel.test.ts b/npm/create-cypress-tests/src/component-testing/templates/react/babel.test.ts deleted file mode 100644 index 1bff7af467af..000000000000 --- a/npm/create-cypress-tests/src/component-testing/templates/react/babel.test.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { expect } from 'chai' -import mockFs from 'mock-fs' -import { BabelTemplate } from './babel' -import { snapshotPluginsAstCode } from '../../../test-utils' - -describe('babel installation template', () => { - beforeEach(mockFs.restore) - - it('resolves babel.config.json', () => { - mockFs({ - '/babel.config.json': JSON.stringify({ - presets: [], - plugins: [], - }), - }) - - const { success } = BabelTemplate.test('/') - - expect(success).to.equal(true) - }) - - it('resolves babel.config.js', () => { - mockFs({ - '/project/babel.config.js': - 'module.exports = { presets: [], plugins: [] };', - '/project/index/package.json': 'dev/null', - }) - - const { success } = BabelTemplate.test('/project/index') - - expect(success).to.equal(true) - }) - - it('resolves babel config from the deep folder', () => { - mockFs({ - '/some/.babelrc': JSON.stringify({ - presets: [], - plugins: [], - }), - '/some/deep/folder/text.txt': '1', - }) - - const { success } = BabelTemplate.test('/some/deep/folder') - - expect(success).to.equal(true) - }) - - it('fails if no babel config found', () => { - mockFs({ - '/some.txt': '1', - }) - - const { success } = BabelTemplate.test('/') - - expect(success).to.equal(false) - }) - - it('resolves babel.config from package.json', () => { - mockFs({ - '/package.json': JSON.stringify({ - babel: { - presets: [], - }, - }), - }) - - const { success } = BabelTemplate.test('/') - - expect(success).to.equal(true) - }) - - it('correctly generates plugins config', () => snapshotPluginsAstCode(BabelTemplate)) -}) diff --git a/npm/create-cypress-tests/src/component-testing/templates/react/babel.ts b/npm/create-cypress-tests/src/component-testing/templates/react/babel.ts deleted file mode 100644 index 5232653d17f8..000000000000 --- a/npm/create-cypress-tests/src/component-testing/templates/react/babel.ts +++ /dev/null @@ -1,43 +0,0 @@ -import chalk from 'chalk' -import findUp from 'find-up' -import * as babel from '@babel/core' -import { Template } from '../Template' -import { createFindPackageJsonIterator } from '../../../findPackageJson' - -export const BabelTemplate: Template = { - message: `It looks like you have babel config defined. We can use it to transpile your components for testing.\n ${chalk.red( - '>>', - )} This is not a replacement for bundling tool. We will use ${chalk.red( - 'webpack', - )} to bundle the components for testing.`, - recommendedComponentFolder: 'cypress/component', - getExampleUrl: () => 'https://github.com/cypress-io/cypress/tree/develop/npm/react/examples/babel', - getPluginsCodeAst: () => { - return { - Require: babel.template.ast('const preprocessor = require(\'@cypress/react/plugins/babel\')'), - ModuleExportsBody: babel.template.ast([ - 'preprocessor(on, config)', - 'return config // IMPORTANT to return the config object', - ].join('\n'), { preserveComments: true }), - } - }, - test: (cwd) => { - const babelConfig = findUp.sync( - ['babel.config.js', 'babel.config.json', '.babelrc', '.babelrc.json'], - { type: 'file', cwd }, - ) - - if (babelConfig) { - return { success: true } - } - - // babel config can also be declared in package.json with `babel` key https://babeljs.io/docs/en/configuration#packagejson - const packageJsonIterator = createFindPackageJsonIterator(cwd) - - return packageJsonIterator.map(({ babel }) => { - return { - success: Boolean(babel), - } - }) - }, -} diff --git a/npm/create-cypress-tests/src/component-testing/templates/react/index.ts b/npm/create-cypress-tests/src/component-testing/templates/react/index.ts deleted file mode 100644 index bbbfca5178fb..000000000000 --- a/npm/create-cypress-tests/src/component-testing/templates/react/index.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Template } from '../Template' -import { NextTemplate } from './next' -import { WebpackTemplate } from './reactWebpackFile' -import { ReactScriptsTemplate } from './react-scripts' -import { BabelTemplate } from './babel' -import { WebpackOptions } from './webpack-options' - -export const reactTemplates: Record> = { - 'create-react-app': ReactScriptsTemplate, - 'next.js': NextTemplate, - webpack: WebpackTemplate, - babel: BabelTemplate, - 'default (webpack options)': WebpackOptions, -} diff --git a/npm/create-cypress-tests/src/component-testing/templates/react/next.test.ts b/npm/create-cypress-tests/src/component-testing/templates/react/next.test.ts deleted file mode 100644 index 4701791877e3..000000000000 --- a/npm/create-cypress-tests/src/component-testing/templates/react/next.test.ts +++ /dev/null @@ -1,77 +0,0 @@ -import sinon, { SinonSpy } from 'sinon' -import { expect, use } from 'chai' -import sinonChai from 'sinon-chai' -import mockFs from 'mock-fs' -import { NextTemplate } from './next' -import { snapshotPluginsAstCode } from '../../../test-utils' - -use(sinonChai) - -describe('next.js install template', () => { - let warnSpy: SinonSpy | null = null - - beforeEach(() => { - warnSpy = sinon.spy(global.console, 'warn') - }) - - afterEach(() => { - mockFs.restore() - warnSpy?.restore() - }) - - it('finds the closest package.json and checks that next is declared as dependency', () => { - mockFs({ - '/package.json': JSON.stringify({ - dependencies: { - next: '^9.2.3', - }, - scripts: { - build: 'next', - }, - }), - }) - - const { success } = NextTemplate.test('/') - - expect(success).to.equal(true) - }) - - it('works if next is declared in the devDependencies as well', () => { - mockFs({ - './package.json': JSON.stringify({ - devDependencies: { - next: '^9.2.3', - }, - scripts: { - build: 'next', - }, - }), - }) - - const { success } = NextTemplate.test(process.cwd()) - - expect(success).to.equal(true) - }) - - it('warns and fails if version is not supported', () => { - mockFs({ - './package.json': JSON.stringify({ - devDependencies: { - next: '^8.2.3', - }, - scripts: { - build: 'next', - }, - }), - }) - - const { success } = NextTemplate.test('i/am/in/some/deep/folder') - - console.log(global.console.warn) - expect(success).to.equal(false) - - expect(global.console.warn).to.be.called - }) - - it('correctly generates plugins config', () => snapshotPluginsAstCode(NextTemplate)) -}) diff --git a/npm/create-cypress-tests/src/component-testing/templates/react/next.ts b/npm/create-cypress-tests/src/component-testing/templates/react/next.ts deleted file mode 100644 index aee4ce57f2d5..000000000000 --- a/npm/create-cypress-tests/src/component-testing/templates/react/next.ts +++ /dev/null @@ -1,54 +0,0 @@ -import * as babel from '@babel/core' -import { createFindPackageJsonIterator } from '../../../findPackageJson' -import { Template } from '../Template' -import { validateSemverVersion } from '../../../utils' -import { MIN_SUPPORTED_VERSION } from '../../versions' - -export const NextTemplate: Template = { - message: 'It looks like you are using next.js.', - getExampleUrl: () => { - return 'https://github.com/cypress-io/cypress/tree/develop/npm/react/examples/nextjs' - }, - recommendedComponentFolder: 'cypress/component', - getPluginsCodeAst: () => { - return { - Require: babel.template.ast('const preprocessor = require(\'@cypress/react/plugins/next\')'), - ModuleExportsBody: babel.template.ast([ - 'preprocessor(on, config)', - 'return config // IMPORTANT to return the config object', - ].join('\n'), { preserveComments: true }), - } - }, - test: (cwd) => { - const packageJsonIterator = createFindPackageJsonIterator(cwd) - - return packageJsonIterator.map(({ dependencies, devDependencies }, path) => { - if (!dependencies && !devDependencies) { - return { success: false } - } - - const allDeps = { - ...(devDependencies || {}), - ...(dependencies || {}), - } as Record - - const nextVersion = allDeps['next'] - - if (!nextVersion) { - return { success: false } - } - - if ( - !validateSemverVersion( - nextVersion, - MIN_SUPPORTED_VERSION['next'], - 'next.js', - ) - ) { - return { success: false } - } - - return { success: true } - }) - }, -} diff --git a/npm/create-cypress-tests/src/component-testing/templates/react/react-scripts.test.ts b/npm/create-cypress-tests/src/component-testing/templates/react/react-scripts.test.ts deleted file mode 100644 index 7bf01624006a..000000000000 --- a/npm/create-cypress-tests/src/component-testing/templates/react/react-scripts.test.ts +++ /dev/null @@ -1,66 +0,0 @@ -import sinon, { SinonSpy } from 'sinon' -import { expect, use } from 'chai' -import sinonChai from 'sinon-chai' -import mockFs from 'mock-fs' -import { ReactScriptsTemplate } from './react-scripts' -import { snapshotPluginsAstCode } from '../../../test-utils' - -use(sinonChai) - -describe('create-react-app install template', () => { - let warnSpy: SinonSpy | null = null - - beforeEach(() => { - warnSpy = sinon.spy(global.console, 'warn') - }) - - afterEach(() => { - mockFs.restore() - warnSpy?.restore() - }) - - it('finds the closest package.json and checks that react-scripts is declared as dependency', () => { - mockFs({ - '/package.json': JSON.stringify({ - dependencies: { - 'react-scripts': '^3.2.3', - }, - }), - }) - - const { success } = ReactScriptsTemplate.test(process.cwd()) - - expect(success).to.equal(true) - }) - - it('works if react-scripts is declared in the devDependencies as well', () => { - mockFs({ - './package.json': JSON.stringify({ - devDependencies: { - 'react-scripts': '^3.2.3', - }, - }), - }) - - const { success } = ReactScriptsTemplate.test(process.cwd()) - - expect(success).to.equal(true) - }) - - it('warns and fails if version is not supported', () => { - mockFs({ - './package.json': JSON.stringify({ - devDependencies: { - 'react-scripts': '^2.2.3', - }, - }), - }) - - const { success } = ReactScriptsTemplate.test(process.cwd()) - - expect(success).to.equal(false) - expect(global.console.warn).to.be.called - }) - - it('correctly generates plugins config', () => snapshotPluginsAstCode(ReactScriptsTemplate)) -}) diff --git a/npm/create-cypress-tests/src/component-testing/templates/react/react-scripts.ts b/npm/create-cypress-tests/src/component-testing/templates/react/react-scripts.ts deleted file mode 100644 index bddd0e5afb22..000000000000 --- a/npm/create-cypress-tests/src/component-testing/templates/react/react-scripts.ts +++ /dev/null @@ -1,61 +0,0 @@ -import chalk from 'chalk' -import { createFindPackageJsonIterator } from '../../../findPackageJson' -import { Template } from '../Template' -import { validateSemverVersion } from '../../../utils' -import { MIN_SUPPORTED_VERSION } from '../../versions' -import * as babel from '@babel/core' - -export const ReactScriptsTemplate: Template = { - recommendedComponentFolder: 'src', - message: 'It looks like you are using create-react-app.', - getExampleUrl: ({ componentFolder }) => { - return componentFolder === 'src' - ? 'https://github.com/cypress-io/cypress/tree/develop/npm/react/examples/react-scripts' - : 'https://github.com/cypress-io/cypress/tree/develop/npm/react/examples/react-scripts-folder' - }, - getPluginsCodeAst: () => { - return { - Require: babel.template.ast('const preprocessor = require(\'@cypress/react/plugins/react-scripts\')'), - ModuleExportsBody: babel.template.ast([ - 'preprocessor(on, config)', - 'return config // IMPORTANT to return the config object', - ].join('\n'), { preserveComments: true }), - } - }, - test: () => { - // TODO also determine ejected create react app - const packageJsonIterator = createFindPackageJsonIterator(process.cwd()) - - return packageJsonIterator.map(({ dependencies, devDependencies }) => { - if (dependencies || devDependencies) { - const allDeps = { ...devDependencies, ...dependencies } || {} - - if (!allDeps['react-scripts']) { - return { success: false } - } - - if ( - !validateSemverVersion( - allDeps['react-scripts'], - MIN_SUPPORTED_VERSION['react-scripts'], - ) - ) { - console.warn( - `It looks like you are using ${chalk.green( - 'create-react-app', - )}, but we support only projects with version ${chalk.bold( - MIN_SUPPORTED_VERSION['react-scripts'], - )} of react-scripts.`, - ) - - // yey found the template - return { success: false } - } - - return { success: true } - } - - return { success: false } - }) - }, -} diff --git a/npm/create-cypress-tests/src/component-testing/templates/react/reactWebpackFile.test.ts b/npm/create-cypress-tests/src/component-testing/templates/react/reactWebpackFile.test.ts deleted file mode 100644 index 4212fcc04f51..000000000000 --- a/npm/create-cypress-tests/src/component-testing/templates/react/reactWebpackFile.test.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { expect } from 'chai' -import mockFs from 'mock-fs' -import { snapshotPluginsAstCode } from '../../../test-utils' -import { WebpackTemplate } from './reactWebpackFile' - -describe('webpack-file install template', () => { - afterEach(mockFs.restore) - - it('resolves webpack.config.js', () => { - mockFs({ - '/webpack.config.js': 'module.exports = { }', - }) - - const { success, payload } = WebpackTemplate.test(process.cwd()) - - expect(success).to.equal(true) - expect(payload?.webpackConfigPath).to.equal('/webpack.config.js') - }) - - it('finds the closest package.json and tries to fetch webpack config path from scrips', () => { - mockFs({ - '/configs/webpack.js': 'module.exports = { }', - '/package.json': JSON.stringify({ - scripts: { - build: 'webpack --config configs/webpack.js', - }, - }), - }) - - const { success, payload } = WebpackTemplate.test(process.cwd()) - - expect(success).to.equal(true) - expect(payload?.webpackConfigPath).to.equal('/configs/webpack.js') - }) - - it('looks for package.json in the upper folder', () => { - mockFs({ - '/i/am/in/some/deep/folder/withFile': 'test', - '/somewhere/configs/webpack.js': 'module.exports = { }', - '/package.json': JSON.stringify({ - scripts: { - build: 'webpack --config somewhere/configs/webpack.js', - }, - }), - }) - - const { success, payload } = WebpackTemplate.test( - 'i/am/in/some/deep/folder', - ) - - expect(success).to.equal(true) - expect(payload?.webpackConfigPath).to.equal('/somewhere/configs/webpack.js') - }) - - it('returns success:false if cannot find webpack config', () => { - mockFs({ - '/a.js': '1', - '/b.js': '2', - }) - - const { success, payload } = WebpackTemplate.test('/') - - expect(success).to.equal(false) - expect(payload).to.equal(undefined) - }) - - it('correctly generates plugins config when webpack config path is missing', () => { - snapshotPluginsAstCode(WebpackTemplate) - }) - - it('correctly generates plugins config when webpack config path is provided', () => { - snapshotPluginsAstCode(WebpackTemplate, { webpackConfigPath: '/config/webpack.config.js' }) - }) -}) diff --git a/npm/create-cypress-tests/src/component-testing/templates/react/reactWebpackFile.ts b/npm/create-cypress-tests/src/component-testing/templates/react/reactWebpackFile.ts deleted file mode 100644 index c977f31afc52..000000000000 --- a/npm/create-cypress-tests/src/component-testing/templates/react/reactWebpackFile.ts +++ /dev/null @@ -1,41 +0,0 @@ -import * as babel from '@babel/core' -import path from 'path' -import { Template } from '../Template' -import { findWebpackConfig } from '../templateUtils' - -export const WebpackTemplate: Template<{ webpackConfigPath: string }> = { - message: - 'It looks like you have custom `webpack.config.js`. We can use it to bundle the components for testing.', - getExampleUrl: () => { - return 'https://github.com/cypress-io/cypress/tree/develop/npm/react/examples/webpack-file' - }, - recommendedComponentFolder: 'cypress/component', - getPluginsCodeAst: (payload, { cypressProjectRoot }) => { - const includeWarnComment = !payload - const webpackConfigPath = payload - ? path.relative(cypressProjectRoot, payload.webpackConfigPath) - : './webpack.config.js' - - return { - Require: babel.template.ast('const preprocessor = require("@cypress/react/plugins/load-webpack")'), - ModuleExportsBody: babel.template.ast([ - includeWarnComment - ? '// TODO replace with valid webpack config path' - : '', - `config.env.webpackFilename = '${webpackConfigPath}'`, - 'preprocessor(on, config)', - 'return config // IMPORTANT to return the config object', - ].join('\n'), { preserveComments: true }), - } - }, - test: (root) => { - const webpackConfigPath = findWebpackConfig(root) - - return webpackConfigPath ? { - success: true, - payload: { webpackConfigPath }, - } : { - success: false, - } - }, -} diff --git a/npm/create-cypress-tests/src/component-testing/templates/react/rollup.test.ts b/npm/create-cypress-tests/src/component-testing/templates/react/rollup.test.ts deleted file mode 100644 index 789419d84da5..000000000000 --- a/npm/create-cypress-tests/src/component-testing/templates/react/rollup.test.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { expect } from 'chai' -import mockFs from 'mock-fs' -import { snapshotPluginsAstCode } from '../../../test-utils' -import { RollupTemplate } from './rollup' - -describe('rollup-file install template', () => { - afterEach(mockFs.restore) - - it('resolves rollup.config.js', () => { - mockFs({ - '/rollup.config.js': 'module.exports = { }', - }) - - const { success, payload } = RollupTemplate.test(process.cwd()) - - expect(success).to.equal(true) - expect(payload?.rollupConfigPath).to.equal('/rollup.config.js') - }) - - it('finds the closest package.json and tries to fetch rollup config path from scrips', () => { - mockFs({ - '/configs/rollup.js': 'module.exports = { }', - '/package.json': JSON.stringify({ - scripts: { - build: 'rollup --config configs/rollup.js', - }, - }), - }) - - const { success, payload } = RollupTemplate.test(process.cwd()) - - expect(success).to.equal(true) - expect(payload?.rollupConfigPath).to.equal('/configs/rollup.js') - }) - - it('looks for package.json in the upper folder', () => { - mockFs({ - '/i/am/in/some/deep/folder/withFile': 'test', - '/somewhere/configs/rollup.js': 'module.exports = { }', - '/package.json': JSON.stringify({ - scripts: { - build: 'rollup --config somewhere/configs/rollup.js', - }, - }), - }) - - const { success, payload } = RollupTemplate.test('i/am/in/some/deep/folder') - - expect(success).to.equal(true) - expect(payload?.rollupConfigPath).to.equal('/somewhere/configs/rollup.js') - }) - - it('returns success:false if cannot find rollup config', () => { - mockFs({ - '/b.js': '2', - '/a.js': '1', - }) - - const { success, payload } = RollupTemplate.test('/') - - expect(success).to.equal(false) - expect(payload).to.equal(undefined) - }) - - it('correctly generates plugins config when webpack config path is missing', () => { - snapshotPluginsAstCode(RollupTemplate) - }) - - it('correctly generates plugins config when webpack config path is provided', () => { - snapshotPluginsAstCode(RollupTemplate, { rollupConfigPath: '/config/rollup.config.js' }) - }) -}) diff --git a/npm/create-cypress-tests/src/component-testing/templates/react/rollup.ts b/npm/create-cypress-tests/src/component-testing/templates/react/rollup.ts deleted file mode 100644 index b56b91dd74da..000000000000 --- a/npm/create-cypress-tests/src/component-testing/templates/react/rollup.ts +++ /dev/null @@ -1,122 +0,0 @@ -import path from 'path' -import chalk from 'chalk' -import findUp from 'find-up' -import highlight from 'cli-highlight' -import { createFindPackageJsonIterator } from '../../../findPackageJson' -import { Template } from '../Template' -import * as babel from '@babel/core' - -export function extractRollupConfigPathFromScript (script: string) { - if (script.includes('rollup ')) { - const cliArgs = script.split(' ').map((part) => part.trim()) - const configArgIndex = cliArgs.findIndex( - (arg) => arg === '--config' || arg === '-c', - ) - - return configArgIndex === -1 ? null : cliArgs[configArgIndex + 1] - } - - return null -} - -export const RollupTemplate: Template<{ rollupConfigPath: string }> = { - message: - 'It looks like you have custom `rollup.config.js`. We can use it to bundle the components for testing.', - getExampleUrl: () => { - return 'https://github.com/cypress-io/cypress/tree/develop/npm/react/examples/rollup' - }, - recommendedComponentFolder: 'src', - getPluginsCodeAst: (payload, { cypressProjectRoot }) => { - const includeWarnComment = !payload - const rollupConfigPath = payload - ? path.relative(cypressProjectRoot, payload.rollupConfigPath) - : 'rollup.config.js' - - return { - Require: babel.template.ast('const rollupPreprocessor = require("@bahmutov/cy-rollup")'), - ModuleExportsBody: babel.template.ast([ - `on(`, - ` 'file:preprocessor',`, - ` rollupPreprocessor({`, - includeWarnComment - ? ' // TODO replace with valid rollup config path' - : '', - ` configFile: '${rollupConfigPath}',`, - ` }),`, - `)`, - ``, - `require('@cypress/code-coverage/task')(on, config)`, - `return config // IMPORTANT to return the config object`, - ].join('\n'), { preserveComments: true }), - } - }, - printHelper: () => { - console.log( - `Make sure that it is also required to add some additional configuration to the ${chalk.red( - 'rollup.config.js', - )}. Here is whats required:`, - ) - - const code = highlight( - [ - `import replace from '@rollup/plugin-replace'`, - `import commonjs from '@rollup/plugin-commonjs'`, - `import nodeResolve from '@rollup/plugin-node-resolve'`, - ``, - `export default [`, - ` {`, - ` plugins: [`, - ` nodeResolve(),`, - ` // process @cypress/react-code`, - ` commonjs(),`, - ` // required for react sources`, - ` replace({ 'process.env.NODE_ENV': JSON.stringify('development') }),`, - ` ]`, - ` }`, - `]`, - ].join('\n'), - { language: 'js' }, - ) - - console.log(`\n${code}\n`) - }, - test: (root) => { - const rollupConfigPath = findUp.sync('rollup.config.js', { cwd: root }) - - if (rollupConfigPath) { - return { - success: true, - payload: { rollupConfigPath }, - } - } - - const packageJsonIterator = createFindPackageJsonIterator(root) - - return packageJsonIterator.map(({ scripts }, packageJsonPath) => { - if (!scripts) { - return { success: false } - } - - for (const script of Object.values(scripts)) { - const rollupConfigRelativePath = extractRollupConfigPathFromScript( - script, - ) - - if (rollupConfigRelativePath) { - const directoryRoot = path.resolve(packageJsonPath, '..') - const rollupConfigPath = path.resolve( - directoryRoot, - rollupConfigRelativePath, - ) - - return { - success: true, - payload: { rollupConfigPath }, - } - } - } - - return { success: false } - }) - }, -} diff --git a/npm/create-cypress-tests/src/component-testing/templates/react/webpack-options-module-exports.template.js b/npm/create-cypress-tests/src/component-testing/templates/react/webpack-options-module-exports.template.js deleted file mode 100644 index 90a4d5b60a33..000000000000 --- a/npm/create-cypress-tests/src/component-testing/templates/react/webpack-options-module-exports.template.js +++ /dev/null @@ -1,29 +0,0 @@ -const opts = webpackPreprocessor.defaultOptions -const babelLoader = opts.webpackOptions.module.rules[0].use[0] - -// add React preset to be able to transpile JSX -babelLoader.options.presets.push(require.resolve('@babel/preset-react')) - -// We can also push Babel istanbul plugin to instrument the code on the fly -// and get code coverage reports from component tests (optional) -if (!babelLoader.options.plugins) { - babelLoader.options.plugins = [] -} - -babelLoader.options.plugins.push(require.resolve('babel-plugin-istanbul')) - -// in order to mock named imports, need to include a plugin -babelLoader.options.plugins.push([ - require.resolve('@babel/plugin-transform-modules-commonjs'), - { - loose: true, - }, -]) - -// add code coverage plugin -require('@cypress/code-coverage/task')(on, config) - -on('file:preprocessor', webpackPreprocessor(opts)) - -// if adding code coverage, important to return updated config -return config diff --git a/npm/create-cypress-tests/src/component-testing/templates/react/webpack-options.ts b/npm/create-cypress-tests/src/component-testing/templates/react/webpack-options.ts deleted file mode 100644 index 7a4240d6fc33..000000000000 --- a/npm/create-cypress-tests/src/component-testing/templates/react/webpack-options.ts +++ /dev/null @@ -1,31 +0,0 @@ -import fs from 'fs' -import path from 'path' -import * as babel from '@babel/core' -import chalk from 'chalk' -import { Template } from '../Template' - -export const WebpackOptions: Template = { - // this should never show ideally - message: `Unable to detect where webpack options are.`, - getExampleUrl: () => { - return 'https://github.com/cypress-io/cypress/tree/develop/npm/react/examples/webpack-options' - }, - test: () => ({ success: false }), - recommendedComponentFolder: 'src', - getPluginsCodeAst: () => { - return { - Require: babel.template.ast('const webpackPreprocessor = require("@cypress/webpack-preprocessor")'), - ModuleExportsBody: babel.template.ast( - fs.readFileSync(path.resolve(__dirname, 'webpack-options-module-exports.template.js'), { encoding: 'utf-8' }), - { preserveComments: true }, - ), - } - }, - printHelper: () => { - console.log( - `${chalk.inverse('Important:')} this configuration is using ${chalk.blue( - 'new webpack configuration ', - )}to bundle components. If you are using some framework (e.g. next) or bundling tool (e.g. rollup/parcel) consider using them to bundle component specs for cypress. \n`, - ) - }, -} diff --git a/npm/create-cypress-tests/src/component-testing/templates/react/webpackOptions.test.ts b/npm/create-cypress-tests/src/component-testing/templates/react/webpackOptions.test.ts deleted file mode 100644 index c7b7e2e6f9a3..000000000000 --- a/npm/create-cypress-tests/src/component-testing/templates/react/webpackOptions.test.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { WebpackOptions } from './webpack-options' -import { snapshotPluginsAstCode } from '../../../test-utils' - -describe('webpack-options template', () => { - it('correctly generates plugins config', () => snapshotPluginsAstCode(WebpackOptions)) -}) diff --git a/npm/create-cypress-tests/src/component-testing/templates/templateUtils.ts b/npm/create-cypress-tests/src/component-testing/templates/templateUtils.ts deleted file mode 100644 index 8b1f8e978f3e..000000000000 --- a/npm/create-cypress-tests/src/component-testing/templates/templateUtils.ts +++ /dev/null @@ -1,53 +0,0 @@ -import findUp from 'find-up' -import path from 'path' -import { createFindPackageJsonIterator } from '../../findPackageJson' - -export function extractWebpackConfigPathFromScript (script: string) { - if (script.includes('webpack ') || script.includes('webpack-dev-server ')) { - const webpackCliArgs = script.split(' ').map((part) => part.trim()) - const configArgIndex = webpackCliArgs.findIndex((arg) => arg === '--config') - - return configArgIndex === -1 ? null : webpackCliArgs[configArgIndex + 1] - } - - return null -} - -export function findWebpackConfig (root: string) { - const webpackConfigPath = findUp.sync('webpack.config.js', { cwd: root }) - - if (webpackConfigPath) { - return webpackConfigPath - } - - const packageJsonIterator = createFindPackageJsonIterator(root) - - const { success, payload } = packageJsonIterator.map(({ scripts }, packageJsonPath) => { - if (!scripts) { - return { success: false } - } - - for (const script of Object.values(scripts)) { - const webpackConfigRelativePath = extractWebpackConfigPathFromScript( - script, - ) - - if (webpackConfigRelativePath) { - const directoryRoot = path.resolve(packageJsonPath, '..') - const webpackConfigPath = path.resolve( - directoryRoot, - webpackConfigRelativePath, - ) - - return { - success: true, - payload: { webpackConfigPath }, - } - } - } - - return { success: false } - }) - - return success ? payload?.webpackConfigPath : null -} diff --git a/npm/create-cypress-tests/src/component-testing/templates/vue/index.ts b/npm/create-cypress-tests/src/component-testing/templates/vue/index.ts deleted file mode 100644 index 512f4ff6ee8d..000000000000 --- a/npm/create-cypress-tests/src/component-testing/templates/vue/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Template } from '../Template' -import { VueCliTemplate } from './vueCli' -import { VueWebpackTemplate } from './vueWebpackFile' - -export const vueTemplates: Record> = { - webpack: VueWebpackTemplate, - 'vue-cli': VueCliTemplate, -} diff --git a/npm/create-cypress-tests/src/component-testing/templates/vue/vueCli.test.ts b/npm/create-cypress-tests/src/component-testing/templates/vue/vueCli.test.ts deleted file mode 100644 index 29bb76b76d2f..000000000000 --- a/npm/create-cypress-tests/src/component-testing/templates/vue/vueCli.test.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { expect } from 'chai' -import mockFs from 'mock-fs' -import { snapshotPluginsAstCode } from '../../../test-utils' -import { VueCliTemplate } from './vueCli' - -describe('vue webpack-file install template', () => { - beforeEach(mockFs.restore) - - it('resolves webpack.config.js', () => { - mockFs({ - '/package.json': JSON.stringify({ - 'devDependencies': { - '@vue/cli-plugin-babel': '~4.5.0', - '@vue/cli-plugin-eslint': '~4.5.0', - '@vue/cli-plugin-router': '~4.5.0', - '@vue/cli-service': '~4.5.0', - }, - }), - }) - - const { success } = VueCliTemplate.test('/') - - expect(success).to.equal(true) - }) - - it('returns success:false if vue-cli-service is not installed', () => { - mockFs({ - '/package.json': JSON.stringify({ - 'devDependencies': { - 'webpack': '*', - 'vue': '2.x', - }, - }), - }) - - const { success } = VueCliTemplate.test('/') - - expect(success).to.equal(false) - }) - - it('correctly generates plugins for vue-cli-service', () => { - snapshotPluginsAstCode(VueCliTemplate) - }) -}) diff --git a/npm/create-cypress-tests/src/component-testing/templates/vue/vueCli.ts b/npm/create-cypress-tests/src/component-testing/templates/vue/vueCli.ts deleted file mode 100644 index 16b117f3e772..000000000000 --- a/npm/create-cypress-tests/src/component-testing/templates/vue/vueCli.ts +++ /dev/null @@ -1,29 +0,0 @@ -import * as babel from '@babel/core' -import { scanFSForAvailableDependency } from '../../../findPackageJson' -import { Template } from '../Template' - -export const VueCliTemplate: Template = { - message: - 'It looks like you are using vue-cli-service to run and build an application.', - getExampleUrl: () => 'https://github.com/cypress-io/cypress/tree/develop/npm/vue/examples/cli', - recommendedComponentFolder: 'src', - getPluginsCodeAst: () => { - return { - Require: babel.template.ast( - 'const preprocessor = require("@cypress/vue/dist/plugins/webpack");', - ), - ModuleExportsBody: babel.template.ast([ - 'preprocessor(on, config);', - '// IMPORTANT return the config object', - 'return config', - ].join('\n'), { preserveComments: true }), - } - }, - test: (root) => { - const hasVueCliService = scanFSForAvailableDependency(root, ['@vue/cli-service']) - - return { - success: hasVueCliService, - } - }, -} diff --git a/npm/create-cypress-tests/src/component-testing/templates/vue/vueWebpackFile.test.ts b/npm/create-cypress-tests/src/component-testing/templates/vue/vueWebpackFile.test.ts deleted file mode 100644 index e0b058958ef2..000000000000 --- a/npm/create-cypress-tests/src/component-testing/templates/vue/vueWebpackFile.test.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { expect } from 'chai' -import mockFs from 'mock-fs' -import { snapshotPluginsAstCode } from '../../../test-utils' -import { VueWebpackTemplate } from './vueWebpackFile' - -describe('vue webpack-file install template', () => { - beforeEach(mockFs.restore) - - it('resolves webpack.config.js', () => { - mockFs({ - '/webpack.config.js': 'module.exports = { }', - }) - - const { success, payload } = VueWebpackTemplate.test(process.cwd()) - - expect(success).to.equal(true) - expect(payload?.webpackConfigPath).to.equal('/webpack.config.js') - }) - - it('finds the closest package.json and tries to fetch webpack config path from scrips', () => { - mockFs({ - '/configs/webpack.js': 'module.exports = { }', - '/package.json': JSON.stringify({ - scripts: { - build: 'webpack --config configs/webpack.js', - }, - }), - }) - - const { success, payload } = VueWebpackTemplate.test(process.cwd()) - - expect(success).to.equal(true) - expect(payload?.webpackConfigPath).to.equal('/configs/webpack.js') - }) - - it('looks for package.json in the upper folder', () => { - mockFs({ - '/some/deep/folder/withFile': 'test', - '/somewhere/configs/webpack.js': 'module.exports = { }', - '/package.json': JSON.stringify({ - scripts: { - build: 'webpack --config somewhere/configs/webpack.js', - }, - }), - }) - - const { success, payload } = VueWebpackTemplate.test( - '/some/deep/folder', - ) - - expect(success).to.equal(true) - expect(payload?.webpackConfigPath).to.equal('/somewhere/configs/webpack.js') - }) - - it('returns success:false if cannot find webpack config', () => { - mockFs({ - '/a.js': '1', - '/b.js': '2', - }) - - const { success, payload } = VueWebpackTemplate.test('/') - - expect(success).to.equal(false) - expect(payload).to.equal(undefined) - }) - - it('correctly generates plugins config when webpack config path is missing', () => { - snapshotPluginsAstCode(VueWebpackTemplate) - }) - - it('correctly generates plugins config when webpack config path is provided', () => { - snapshotPluginsAstCode(VueWebpackTemplate, { webpackConfigPath: '/build/webpack.config.js' }) - }) -}) diff --git a/npm/create-cypress-tests/src/component-testing/templates/vue/vueWebpackFile.ts b/npm/create-cypress-tests/src/component-testing/templates/vue/vueWebpackFile.ts deleted file mode 100644 index 1e49d1a9ddc8..000000000000 --- a/npm/create-cypress-tests/src/component-testing/templates/vue/vueWebpackFile.ts +++ /dev/null @@ -1,41 +0,0 @@ -import * as babel from '@babel/core' -import path from 'path' -import { Template } from '../Template' -import { findWebpackConfig } from '../templateUtils' - -export const VueWebpackTemplate: Template<{ webpackConfigPath: string }> = { - message: - 'It looks like you have custom `webpack.config.js`. We can use it to bundle the components for testing.', - getExampleUrl: () => 'https://github.com/cypress-io/cypress/tree/develop/npm/vue/examples/cli', - recommendedComponentFolder: 'cypress/component', - getPluginsCodeAst: (payload, { cypressProjectRoot }) => { - const includeWarnComment = !payload - const webpackConfigPath = payload - ? path.relative(cypressProjectRoot, payload.webpackConfigPath) - : './webpack.config.js' - - return { - Require: babel.template.ast([ - 'const {', - ' onFilePreprocessor', - '} = require(\'@cypress/vue/dist/preprocessor/webpack\')', - ].join('\n')), - ModuleExportsBody: babel.template.ast([ - includeWarnComment - ? '// TODO replace with valid webpack config path' - : '', - `on('file:preprocessor', onFilePreprocessor('${webpackConfigPath}'))`, - ].join('\n'), { preserveComments: true }), - } - }, - test: (root) => { - const webpackConfigPath = findWebpackConfig(root) - - return webpackConfigPath ? { - success: true, - payload: { webpackConfigPath }, - } : { - success: false, - } - }, -} diff --git a/npm/create-cypress-tests/src/component-testing/versions.ts b/npm/create-cypress-tests/src/component-testing/versions.ts deleted file mode 100644 index ce3ac3ae04d5..000000000000 --- a/npm/create-cypress-tests/src/component-testing/versions.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const MIN_SUPPORTED_VERSION = { - 'react-scripts': '^=3.x || ^=4.x', - next: '^=9.x', -} diff --git a/npm/create-cypress-tests/src/findPackageJson.ts b/npm/create-cypress-tests/src/findPackageJson.ts deleted file mode 100644 index f52fcdd52fa6..000000000000 --- a/npm/create-cypress-tests/src/findPackageJson.ts +++ /dev/null @@ -1,110 +0,0 @@ -import path from 'path' -import fs from 'fs' -import findUp from 'find-up' - -type PackageJsonLike = { - name?: string - scripts?: Record - dependencies?: Record - devDependencies?: Record - [key: string]: unknown -} - -type FindPackageJsonResult = - | { - packageData: PackageJsonLike - filename: string - done: false - } - | { - packageData: undefined - filename: undefined - done: true - } - -/** - * Return the parsed package.json that we find in a parent folder. - * - * @returns {Object} Value, filename and indication if the iteration is done. - */ -export function createFindPackageJsonIterator (rootPath = process.cwd()) { - function scanForPackageJson (cwd: string): FindPackageJsonResult { - const packageJsonPath = findUp.sync('package.json', { cwd }) - - if (!packageJsonPath) { - return { - packageData: undefined, - filename: undefined, - done: true, - } - } - - const packageData = JSON.parse( - fs.readFileSync(packageJsonPath, { - encoding: 'utf-8', - }), - ) - - return { - packageData, - filename: packageJsonPath, - done: false, - } - } - - return { - map: ( - cb: ( - data: PackageJsonLike, - packageJsonPath: string, - ) => { success: boolean, payload?: TPayload }, - ) => { - let stepPathToScan = rootPath - - // eslint-disable-next-line - while (true) { - const result = scanForPackageJson(stepPathToScan) - - if (result.done) { - // didn't find the package.json - return { success: false } - } - - if (result.packageData) { - const cbResult = cb(result.packageData, result.filename) - - if (cbResult.success) { - return { success: true, payload: cbResult.payload } - } - } - - const nextStepPathToScan = path.resolve(stepPathToScan, '..') - - if (nextStepPathToScan === stepPathToScan) { - // we are at the root. Give up - return { success: false } - } - - stepPathToScan = nextStepPathToScan - } - }, - } -} - -export function scanFSForAvailableDependency (cwd: string, deps: string[]) { - const { success } = createFindPackageJsonIterator(cwd) - .map(({ dependencies, devDependencies }, path) => { - if (!dependencies && !devDependencies) { - return { success: false } - } - - return { - success: Object.keys({ ...dependencies, ...devDependencies }) - .some((dependency) => deps.includes(dependency)), - } - }) - - return success -} - -export type PackageJsonIterator = ReturnType diff --git a/npm/create-cypress-tests/src/index.ts b/npm/create-cypress-tests/src/index.ts deleted file mode 100644 index 9e6e68e3f4ec..000000000000 --- a/npm/create-cypress-tests/src/index.ts +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env node -import { program } from 'commander' -import { main } from './main' -import { version } from '../package.json' - -program -.option('--ignore-examples', 'Ignore generating example tests and fixtures by creating one ready-to-fill spec file') -.option('--use-npm', 'Use npm even if yarn is available') -.option('--ignore-ts', 'Ignore typescript if available') -.option('--component-tests', 'Run component testing installation without asking') - -program.version(version, '-v --version') -program.parse(process.argv) - -main({ - useNpm: program.useNpm, - ignoreTs: program.ignoreTs, - ignoreExamples: Boolean(program.ignoreExamples), - setupComponentTesting: program.componentTests, -}).catch(console.error) diff --git a/npm/create-cypress-tests/src/installCypress.ts b/npm/create-cypress-tests/src/installCypress.ts deleted file mode 100644 index d44171dd7305..000000000000 --- a/npm/create-cypress-tests/src/installCypress.ts +++ /dev/null @@ -1,71 +0,0 @@ -import fs from 'fs-extra' -import findUp from 'find-up' -import path from 'path' -import example from '../initial-template' -import { installDependency } from './utils' -import chalk from 'chalk' -import ora from 'ora' - -type InstallCypressOpts = { - useYarn: boolean - useTypescript: boolean - ignoreExamples: boolean -} - -async function copyFiles ({ ignoreExamples, useTypescript }: InstallCypressOpts) { - let fileSpinner = ora('Creating config files').start() - - await fs.outputFile(path.resolve(process.cwd(), 'cypress.json'), '{}\n') - await fs.copy(example.getPathToPlugins(), path.resolve('cypress', 'plugins/index.js')) - const supportFiles: string[] = await example.getPathToSupportFiles() - - await Promise.all( - supportFiles.map((supportFilePath) => { - const newSupportFilePath = path.resolve('cypress', 'support', path.basename(supportFilePath)) - - return fs.copy(supportFilePath, newSupportFilePath) - }), - ) - - if (useTypescript) { - await fs.copy(example.getPathToTsConfig(), path.resolve('cypress', 'tsconfig.json')) - } - - // TODO think about better approach - if (ignoreExamples) { - const dummySpec = [ - 'describe("Spec", () => {', - '', - '})', - '', - ] - const specFileToCreate = path.resolve('cypress', 'integration', useTypescript ? 'spec.ts' : 'spec.js') - - await fs.outputFile(path.resolve('cypress', 'integration', useTypescript ? 'spec.js' : 'spec.ts'), dummySpec) - console.log(`In order to ignore examples a spec file ${chalk.green(path.relative(process.cwd(), specFileToCreate))}.`) - } - - fileSpinner.succeed() -} - -export async function findInstalledOrInstallCypress (options: InstallCypressOpts) { - let cypressJsonPath = await findUp('cypress.json') - - if (!cypressJsonPath) { - await installDependency('cypress', options) - await copyFiles(options) - - cypressJsonPath = await findUp('cypress.json') - } - - if (!cypressJsonPath) { - throw new Error('Unexpected error during cypress installation.') - } - - return { - cypressConfigPath: cypressJsonPath, - config: JSON.parse( - fs.readFileSync(cypressJsonPath, { encoding: 'utf-8' }).toString(), - ) as Record, - } -} diff --git a/npm/create-cypress-tests/src/main.test.ts b/npm/create-cypress-tests/src/main.test.ts deleted file mode 100644 index 324c33f8db27..000000000000 --- a/npm/create-cypress-tests/src/main.test.ts +++ /dev/null @@ -1,160 +0,0 @@ -import { expect, use } from 'chai' -import path from 'path' -import sinon, { SinonStub, SinonSpy, SinonSpyCallApi, restore } from 'sinon' -import mockFs from 'mock-fs' -import fsExtra from 'fs-extra' -import { main } from './main' -import sinonChai from 'sinon-chai' -import childProcess from 'child_process' - -use(sinonChai) - -function someOfSpyCallsIncludes (spy: any, logPart: string) { - return spy.getCalls().some( - (spy: SinonSpyCallApi) => { - return spy.args.some((callArg) => typeof callArg === 'string' && callArg.includes(logPart)) - }, - ) -} - -describe('create-cypress-tests', () => { - let promptSpy: SinonStub | null = null - let logSpy: SinonSpy | null = null - let errorSpy: SinonSpy | null = null - let execStub: SinonStub | null = null - let fsCopyStub: SinonStub | null = null - let processExitStub: SinonStub | null = null - - beforeEach(() => { - logSpy = sinon.spy(global.console, 'log') - errorSpy = sinon.spy(global.console, 'error') - // @ts-ignore - execStub = sinon.stub(childProcess, 'exec').callsFake((command, callback) => callback()) - // @ts-ignore - fsCopyStub = sinon.stub(fsExtra, 'copy').returns(Promise.resolve()) - processExitStub = sinon.stub(process, 'exit').callsFake(() => { - throw new Error('process.exit should not be called') - }) - }) - - afterEach(() => { - mockFs.restore() - logSpy?.restore() - promptSpy?.restore() - execStub?.restore() - fsCopyStub?.restore() - processExitStub?.restore() - execStub?.restore() - errorSpy?.restore() - }) - - it('Install cypress if no config found', async () => { - mockFs({ - '/package.json': JSON.stringify({ }), - }) - - await main({ useNpm: false, ignoreTs: false, ignoreExamples: false, setupComponentTesting: false }) - - expect(execStub).calledWith('yarn add cypress --dev') - }) - - it('Uses npm if yarn is not available', async () => { - execStub - ?.onFirstCall().callsFake((command, callback) => callback('yarn is not available')) - ?.onSecondCall().callsFake((command, callback) => callback()) - ?.onThirdCall().callsFake((command, callback) => callback()) - - mockFs({ - '/package.json': JSON.stringify({ }), - }) - - await main({ useNpm: false, ignoreTs: false, ignoreExamples: false, setupComponentTesting: false }) - expect(execStub).calledWith('npm install -D cypress') - }) - - it('Uses npm if --use-npm was provided', async () => { - mockFs({ - '/package.json': JSON.stringify({ }), - }) - - await main({ useNpm: true, ignoreTs: false, ignoreExamples: false, setupComponentTesting: false }) - - expect(execStub).calledWith('npm install -D cypress') - }) - - it('Prints correct commands helper for npm', async () => { - mockFs({ - '/package.json': JSON.stringify({ }), - }) - - await main({ useNpm: true, ignoreTs: false, ignoreExamples: false, setupComponentTesting: false }) - expect(someOfSpyCallsIncludes(logSpy, 'npx cypress open')).to.be.true - }) - - it('Prints correct commands helper for yarn', async () => { - mockFs({ - '/package.json': JSON.stringify({ }), - }) - - await main({ useNpm: false, ignoreTs: false, ignoreExamples: false, setupComponentTesting: false }) - expect(someOfSpyCallsIncludes(logSpy, 'yarn cypress open')).to.be.true - }) - - it('Fails if git repository have untracked or uncommited files', async () => { - mockFs({ - '/package.json': JSON.stringify({ }), - }) - - execStub?.callsFake((_, callback) => callback(null, { stdout: 'test' })) - processExitStub?.callsFake(() => {}) - - await main({ useNpm: true, ignoreTs: false, ignoreExamples: false, setupComponentTesting: false }) - - expect( - someOfSpyCallsIncludes(errorSpy, 'This repository has untracked files or uncommmited changes.'), - ).to.equal(true) - - expect(processExitStub).to.be.called - }) - - context('e2e fs tests', () => { - const e2eTestOutputPath = path.resolve(__dirname, 'test-output') - - beforeEach(async () => { - fsCopyStub?.restore() - mockFs.restore() - sinon.stub(process, 'cwd').returns(e2eTestOutputPath) - - await fsExtra.remove(e2eTestOutputPath) - await fsExtra.mkdir(e2eTestOutputPath) - }) - - it('Copies plugins and support files', async () => { - await fsExtra.outputFile( - path.join(e2eTestOutputPath, 'package.json'), - JSON.stringify({ name: 'test' }, null, 2), - ) - - await main({ useNpm: true, ignoreTs: false, ignoreExamples: false, setupComponentTesting: false }) - - expect(await fsExtra.pathExists(path.resolve(e2eTestOutputPath, 'cypress', 'plugins', 'index.js'))).to.equal(true) - expect(await fsExtra.pathExists(path.resolve(e2eTestOutputPath, 'cypress', 'support', 'index.js'))).to.equal(true) - expect(await fsExtra.pathExists(path.resolve(e2eTestOutputPath, 'cypress', 'support', 'commands.js'))).to.equal(true) - expect(await fsExtra.pathExists(path.resolve(e2eTestOutputPath, 'cypress.json'))).to.equal(true) - }) - - it('Copies tsconfig if typescript is installed', async () => { - await fsExtra.outputFile( - path.join(e2eTestOutputPath, 'package.json'), - JSON.stringify({ - name: 'test-typescript', - dependencies: { typescript: '^4.0.0' }, - }, null, 2), - ) - - await main({ useNpm: false, ignoreTs: false, ignoreExamples: false, setupComponentTesting: false }) - await fsExtra.pathExists(path.resolve(e2eTestOutputPath, 'cypress', 'tsconfig.json')) - console.log(path.resolve(e2eTestOutputPath, 'cypress', 'tsconfig.json')) - }) - }) -}) diff --git a/npm/create-cypress-tests/src/main.ts b/npm/create-cypress-tests/src/main.ts deleted file mode 100644 index d5fedf74a0fe..000000000000 --- a/npm/create-cypress-tests/src/main.ts +++ /dev/null @@ -1,98 +0,0 @@ -import fs from 'fs' -import findUp from 'find-up' -import chalk from 'chalk' -import util from 'util' -import inquirer from 'inquirer' -import { initComponentTesting } from './component-testing/init-component-testing' -import { exec } from 'child_process' -import { scanFSForAvailableDependency } from './findPackageJson' -import { findInstalledOrInstallCypress } from './installCypress' - -type MainArgv = { - useNpm: boolean - ignoreTs: boolean - ignoreExamples: boolean - setupComponentTesting: boolean -} - -async function getGitStatus () { - const execAsync = util.promisify(exec) - - try { - let { stdout } = await execAsync(`git status --porcelain`) - - console.log(stdout) - - return stdout.trim() - } catch (e) { - return '' - } -} - -async function shouldUseYarn () { - const execAsync = util.promisify(exec) - - return execAsync('yarn --version') - .then(() => true) - .catch(() => false) -} - -function shouldUseTypescript () { - return scanFSForAvailableDependency(process.cwd(), ['typescript']) -} - -async function askForComponentTesting () { - const { shouldSetupComponentTesting } = await inquirer.prompt({ - type: 'confirm', - name: 'shouldSetupComponentTesting', - message: `Do you want to setup ${chalk.cyan('component testing')}? ${chalk.grey('You can do this later by rerunning this command')}.`, - }) - - return shouldSetupComponentTesting -} - -function printCypressCommandsHelper ({ useYarn }: { useYarn: boolean }) { - const displayedCommand = useYarn ? 'yarn' : 'npx' - - console.log('Inside this directory, you can run several commands:') - console.log() - console.log(chalk.cyan(` ${displayedCommand} cypress open`)) - console.log(' Opens cypress local development app.') - console.log() - console.log(chalk.cyan(` ${displayedCommand} cypress run`)) - console.log(' Runs tests in headless mode.') -} - -export async function main ({ useNpm, ignoreTs, setupComponentTesting, ignoreExamples }: MainArgv) { - const rootPackageJsonPath = await findUp('package.json') - const useYarn = useNpm === true ? false : await shouldUseYarn() - const useTypescript = ignoreTs ? false : shouldUseTypescript() - - if (!rootPackageJsonPath) { - console.log(`${chalk.bold.red(`It looks like you are running cypress installation wizard outside of npm module.`)}\nIf you would like to setup a new project for cypress tests please run the ${chalk.inverse(useNpm ? ' npm init ' : ' yarn init ')} first.`) - process.exit(1) - } - - const { name = 'unknown', version = '0.0.0' } = JSON.parse(fs.readFileSync(rootPackageJsonPath).toString()) - - console.log(`Running ${chalk.green('cypress ๐ŸŒฒ')} installation wizard for ${chalk.cyan(`${name}@${version}`)}`) - - const gitStatus = await getGitStatus() - - if (gitStatus) { - console.error(`\n${chalk.bold.red('This repository has untracked files or uncommmited changes.')}\nThis command will ${chalk.cyan('make changes in the codebase')}, so please remove untracked files, stash or commit any changes, and try again.`) - process.exit(1) - } - - const { config, cypressConfigPath } = await findInstalledOrInstallCypress({ useYarn, useTypescript, ignoreExamples }) - const shouldSetupComponentTesting = setupComponentTesting ?? await askForComponentTesting() - - if (shouldSetupComponentTesting) { - await initComponentTesting({ config, cypressConfigPath, useYarn }) - } - - console.log(`\n๐Ÿ‘ Success! Cypress is installed and ready to run tests.`) - printCypressCommandsHelper({ useYarn }) - - console.log(`\nHappy testing with ${chalk.green('cypress.io')} ๐ŸŒฒ\n`) -} diff --git a/npm/create-cypress-tests/src/test-utils.ts b/npm/create-cypress-tests/src/test-utils.ts deleted file mode 100644 index 6021690678b9..000000000000 --- a/npm/create-cypress-tests/src/test-utils.ts +++ /dev/null @@ -1,34 +0,0 @@ -import * as babel from '@babel/core' -import snapshot from 'snap-shot-it' -import mockFs from 'mock-fs' -import { SinonSpyCallApi } from 'sinon' -import { createTransformPluginsFileBabelPlugin } from './component-testing/babel/babelTransform' -import { Template } from './component-testing/templates/Template' - -export function someOfSpyCallsIncludes (spy: any, logPart: string) { - return spy.getCalls().some( - (spy: SinonSpyCallApi) => { - return spy.args.some((callArg) => typeof callArg === 'string' && callArg.includes(logPart)) - }, - ) -} - -export function snapshotPluginsAstCode (template: Template, payload?: T) { - mockFs.restore() - const code = [ - 'const something = require("something")', - 'module.exports = (on) => {', - '};', - ].join('\n') - - const babelPlugin = createTransformPluginsFileBabelPlugin(template.getPluginsCodeAst(payload ?? null, { cypressProjectRoot: '/' })) - const output = babel.transformSync(code, { - plugins: [babelPlugin], - }) - - if (!output || !output.code) { - throw new Error('Babel transform output is empty.') - } - - snapshot(output.code) -} diff --git a/npm/create-cypress-tests/src/utils.ts b/npm/create-cypress-tests/src/utils.ts deleted file mode 100644 index c42a92855e93..000000000000 --- a/npm/create-cypress-tests/src/utils.ts +++ /dev/null @@ -1,62 +0,0 @@ -import semver from 'semver' -import chalk from 'chalk' -import ora from 'ora' -import util from 'util' -import { exec } from 'child_process' - -/** - * Compare available version range with the provided version from package.json - * @param packageName Package name used to display a helper message to user. - */ -export function validateSemverVersion ( - version: string, - allowedVersionRange: string, - packageName?: string, -) { - let isValid: boolean - - try { - const minAvailableVersion = semver.minVersion(version)?.raw - - isValid = Boolean( - minAvailableVersion && - semver.satisfies(minAvailableVersion, allowedVersionRange), - ) - } catch (e) { - // handle not semver versions like "latest", "git:" or "file:" - isValid = false - } - - if (!isValid && packageName) { - const packageNameSymbol = chalk.green(packageName) - - console.warn( - `It seems like you are using ${packageNameSymbol} with version ${chalk.bold( - version, - )}, however we support only ${packageNameSymbol} projects with version ${chalk.bold( - allowedVersionRange, - )}. \n`, - ) - } - - return isValid -} - -export async function installDependency (name: string, options: { useYarn: boolean}) { - const commandToRun = options.useYarn ? `yarn add ${name} --dev` : `npm install -D ${name}` - let cliSpinner = ora(`Installing ${name} ${chalk.gray(`(${commandToRun})`)}`).start() - - try { - // do this inside function for test stubbing - const execAsync = util.promisify(exec) - - await execAsync(commandToRun) - } catch (e) { - cliSpinner.fail(`Can not install ${name} using ${chalk.inverse(commandToRun)})}`) - console.log(e) - - process.exit(1) - } - - cliSpinner.succeed() -} diff --git a/npm/create-cypress-tests/tsconfig.json b/npm/create-cypress-tests/tsconfig.json deleted file mode 100644 index ea3235694af0..000000000000 --- a/npm/create-cypress-tests/tsconfig.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "compilerOptions": { - "outDir": "./dist", - "rootDir": ".", - "esModuleInterop": true, - "allowJs": true, - "allowSyntheticDefaultImports": true, - "declaration": true, - "moduleResolution": "node", - "strict": true, - "strictNullChecks": true, - "resolveJsonModule": true, - "module": "CommonJS", - "target": "ES2018", - "types": [ - "node", - ], - "lib": [ - "ES2018" - ], - "noImplicitAny": true - }, - "exclude": [ - "./src/**/*.test.ts", - "node_modules" - ], - "include": [ - "./src/**/*.ts", - "./initial-template/**/*.{js}" - ] -} diff --git a/npm/create-cypress-tests/tsconfig.test.json b/npm/create-cypress-tests/tsconfig.test.json deleted file mode 100644 index df01205d9a40..000000000000 --- a/npm/create-cypress-tests/tsconfig.test.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "noEmit": true, - "types": [ - "mocha" - ] - }, - "include": [ - "./src/**/*.test.ts" - ] -} \ No newline at end of file diff --git a/npm/react/circle.yml b/npm/react/circle.yml new file mode 100644 index 000000000000..7c3c683094ef --- /dev/null +++ b/npm/react/circle.yml @@ -0,0 +1,371 @@ +version: 2.1 +orbs: + cypress: cypress-io/cypress@1.26.0 + +workflows: + build: + jobs: + # install and cache dependencies in this job + # AND build the library once + # then the workspace will be passed to other jobs + - cypress/install: + name: Install + executor: cypress/base-12 + build: npm run transpile + post-steps: + - run: + name: Show info ๐Ÿ“บ + command: npx cypress info + - run: + name: Linting code ๐Ÿงน + command: npm run lint + - run: + name: Stop exclusive tests 1๏ธโƒฃ + command: npm run stop-only + - run: + name: Build folder ๐Ÿ— + command: npm run build + - run: + name: Run unit tests ๐Ÿ‘ท + command: npm run test:unit + + - cypress/run: + name: Example A11y + requires: + - Install + executor: cypress/base-12 + # each example installs "cypress-react-unit-test" as a local dependency (symlink) + install-command: npm install --no-bin-links + verify-command: echo 'Already verified' + no-workspace: true + working_directory: examples/a11y + command: npm test + store_artifacts: true + + - cypress/run: + name: Example Babel + requires: + - Install + executor: cypress/base-12 + # each example installs "cypress-react-unit-test" as a local dependency (symlink) + install-command: npm install --no-bin-links + verify-command: echo 'Already verified' + no-workspace: false + working_directory: examples/using-babel + command: npm test + store_artifacts: true + + - cypress/run: + name: Example Babel + Typescript + requires: + - Install + executor: cypress/base-12 + # each example installs "cypress-react-unit-test" as a local dependency (symlink) + install-command: npm install --no-bin-links + verify-command: echo 'Already verified' + no-workspace: true + working_directory: examples/using-babel-typescript + command: npm test + store_artifacts: true + + - cypress/run: + name: Example React Scripts + requires: + - Install + executor: cypress/base-12 + # each example installs "cypress-react-unit-test" as a local dependency (symlink) + install-command: npm install --no-bin-links + verify-command: echo 'Already verified' + no-workspace: true + working_directory: examples/react-scripts + command: npm test + store_artifacts: true + post-steps: + - run: + name: Check coverage ๐Ÿ“ˆ + command: | + npm run check-coverage + npm run only-covered + working_directory: examples/react-scripts + + - cypress/run: + name: Example Next.js + requires: + - Install + executor: cypress/base-12 + # each example installs "cypress-react-unit-test" as a local dependency (symlink) + install-command: npm install --no-bin-links + verify-command: echo 'Already verified' + no-workspace: true + working_directory: examples/nextjs + command: npm test + store_artifacts: true + post-steps: + - run: + name: Check coverage ๐Ÿ“ˆ + command: | + npm run check-coverage + npm run only-covered + working_directory: examples/nextjs + + - cypress/run: + # react-scripts example with component tests not in "src" folder + # but in "cypress/component" folder + name: Example Component Folder + executor: cypress/base-12 + requires: + - Install + # each example installs "cypress-react-unit-test" as a local dependency (symlink) + install-command: npm install --no-bin-links + verify-command: echo 'Already verified' + no-workspace: true + working_directory: examples/react-scripts-folder + command: npm test + store_artifacts: true + post-steps: + - run: + name: Check coverage ๐Ÿ“ˆ + command: | + npm run check-coverage + npm run only-covered + working_directory: examples/react-scripts-folder + + - cypress/run: + name: Example Tailwind + requires: + - Install + # each example installs "cypress-react-unit-test" as a local dependency (symlink) + executor: cypress/base-12 + install-command: npm install --no-bin-links + verify-command: echo 'Already verified' + no-workspace: true + working_directory: examples/tailwind + command: | + DEBUG=cypress-react-unit-test,find-webpack npm test + store_artifacts: true + post-steps: + - run: + name: Check coverage ๐Ÿ“ˆ + command: | + ls -la + npm run check-coverage + npm run only-covered + working_directory: examples/tailwind + + - cypress/run: + name: Example Webpack file + requires: + - Install + # each example installs "cypress-react-unit-test" as a local dependency (symlink) + executor: cypress/base-12 + install-command: npm install --no-bin-links + verify-command: echo 'Already verified' + no-workspace: true + working_directory: examples/webpack-file + command: npm test + store_artifacts: true + post-steps: + - run: + name: Check coverage ๐Ÿ“ˆ + command: | + npm run check-coverage + npm run only-covered + working_directory: examples/webpack-file + + - cypress/run: + name: Example Rollup + requires: + - Install + # each example installs "cypress-react-unit-test" as a local dependency (symlink) + executor: cypress/base-12 + install-command: npm install --no-bin-links + verify-command: echo 'Already verified' + no-workspace: true + working_directory: examples/rollup + command: npm test + store_artifacts: true + + - cypress/run: + name: Example Webpack options + requires: + - Install + # each example installs "cypress-react-unit-test" as a local dependency (symlink) + executor: cypress/base-12 + install-command: npm install --no-bin-links + verify-command: echo 'Already verified' + no-workspace: true + working_directory: examples/webpack-options + command: npm test + store_artifacts: true + post-steps: + - run: + name: Check coverage ๐Ÿ“ˆ + command: | + npm run check-coverage + npm run only-covered + working_directory: examples/webpack-options + +# - cypress/run: +# name: Example Sass +# requires: +# - Install +# # we need the same OS version as in install job +# # because we will use native Sass dependency +# executor: cypress/base-12 +# # each example installs "cypress-react-unit-test" as a local dependency (symlink) +# install-command: npm install --no-bin-links +# verify-command: echo 'Already verified' +# no-workspace: true +# working_directory: examples/sass-and-ts +# command: npm test +# store_artifacts: true +# post-steps: +# - run: +# name: Check coverage ๐Ÿ“ˆ +# command: | +# npm run check-coverage +# npm run only-covered +# working_directory: examples/sass-and-ts + + - cypress/run: + name: Example Snapshots + requires: + - Install + executor: cypress/base-12 + # each example installs "cypress-react-unit-test" as a local dependency (symlink) + install-command: npm install --no-bin-links + verify-command: echo 'Already verified' + no-workspace: true + working_directory: examples/snapshots + command: npm test + store_artifacts: true + + - cypress/run: + name: Visual Sudoku + executor: cypress/base-12 + requires: + - Install + # each example installs "cypress-react-unit-test" as a local dependency (symlink) + install-command: npm install --no-bin-links + verify-command: echo 'Already verified' + no-workspace: true + working_directory: examples/visual-sudoku + command: npm test + store_artifacts: true + post-steps: + - store_artifacts: + path: examples/visual-sudoku/cypress/snapshots + + - cypress/run: + name: Visual with Applitools + executor: cypress/base-12 + requires: + - Install + # each example installs "cypress-react-unit-test" as a local dependency (symlink) + install-command: npm install --no-bin-links + verify-command: echo 'Already verified' + no-workspace: true + working_directory: examples/visual-testing-with-applitools + # to correctly run this job, we need Applitools token + # external pull requests do not have environment variables set + # thus the job will always fail. Let's skip this job if the + # environment variable is missing + command: | + if [ -z "$APPLITOOLS_API_KEY" ]; then + echo "Skipping Applitools test job, missing environment variable APPLITOOLS_API_KEY" + else + npm test + fi + store_artifacts: true + + - cypress/run: + name: Visual with Percy + executor: cypress/base-12 + requires: + - Install + # each example installs "cypress-react-unit-test" as a local dependency (symlink) + install-command: npm install --no-bin-links + verify-command: echo 'Already verified' + no-workspace: true + working_directory: examples/visual-testing-with-percy + # run Percy agent and then run Cypress component tests + # https://docs.percy.io/docs/cypress + command: npx percy exec -- npm test + store_artifacts: true + + - cypress/run: + name: Visual with Happo + executor: cypress/base-12 + requires: + - Install + # each example installs "cypress-react-unit-test" as a local dependency (symlink) + install-command: npm install --no-bin-links + verify-command: echo 'Already verified' + no-workspace: true + working_directory: examples/visual-testing-with-happo + command: npm run test:happo + store_artifacts: true + + - cypress/run: + name: Component Tests + executor: cypress/base-12 + parallelism: 4 + requires: + - Install + # notice a trick to avoid re-installing dependencies + # in this job - a do-nothing "install-command" parameter + install-command: echo 'Nothing to install in this job' + # we are not going to use results from this job anywhere else + no-workspace: true + record: false + store_artifacts: true + # following examples from + # https://circleci.com/docs/2.0/parallelism-faster-jobs/ + # TODO probably only run component tests and move integration sanity checks into own job + command: | + TESTFILES=$(circleci tests glob "cypress/{component,integration}/**/*spec.{js,jsx,ts,tsx}" | circleci tests split --total=4) + echo "Test files for this machine are $TESTFILES" + npx cypress run --spec $TESTFILES + + # this job attaches the workspace left by the install job + # so it is ready to run Cypress tests + # only we will run semantic release script instead + - cypress/run: + name: NPM release + # only run NPM release from specific branch(es) + filters: + branches: + only: + - main + # we need newer Node for semantic release + executor: cypress/base-12 + requires: + - Install + - Component Tests + - Example A11y + - Example Babel + - Example Component Folder + - Example React Scripts + # - Example Sass + - Example Snapshots + - Example Tailwind + - Example Webpack file + - Example Webpack options + - Example Rollup + - Visual Sudoku + - Visual with Percy + - Visual with Happo + - Visual with Applitools + install-command: echo 'Already installed' + verify-command: echo 'Already verified' + no-workspace: true + # instead of "cypress run" do NPM release ๐Ÿ˜ + # clear environment variables to trick semantic-release + # into thinking this is NOT a pull request. + # (under the hood the module env-ci is used to check if this is a PR) + command: | + npm run build + CIRCLE_PR_NUMBER= \ + CIRCLE_PULL_REQUEST= \ + CI_PULL_REQUEST= \ + npm run semantic-release diff --git a/npm/react/package.json b/npm/react/package.json index 2d4f862e90c7..9db22c9803f6 100644 --- a/npm/react/package.json +++ b/npm/react/package.json @@ -43,6 +43,9 @@ "@percy/cypress": "2.3.2", "@testing-library/cypress": "7.0.1", "@types/chalk": "2.2.0", + "@types/inquirer": "7.3.1", + "@types/mock-fs": "4.10.0", + "@types/node": "9.6.49", "@types/semver": "7.3.4", "arg": "4.1.3", "autoprefixer": "9.7.6", @@ -64,6 +67,8 @@ "lodash": "4.17.15", "mobx": "6.0.0", "mobx-react-lite": "3.0.0", + "mocha": "7.1.1", + "mock-fs": "4.13.0", "next": "^9.5.3", "pretty": "2.0.0", "prop-types": "15.7.2", @@ -95,7 +100,7 @@ "@types/react": "^16.9.16", "babel-loader": "^=8.x", "cypress": "*", - "next": "^=9.x", + "next": "^=8.x", "react": "^=16.x", "react-dom": "^=16.x", "webpack": "^=3.x" diff --git a/npm/vue/src/preprocessor/webpack.js b/npm/vue/src/preprocessor/webpack.js index 4874533f0936..6a28bc6ec663 100644 --- a/npm/vue/src/preprocessor/webpack.js +++ b/npm/vue/src/preprocessor/webpack.js @@ -60,6 +60,7 @@ function compileTemplate (options = {}) { /** * Warning: modifies the input object +<<<<<<< HEAD * @param {WebpackOptions} options */ @@ -75,6 +76,8 @@ function removeForkTsCheckerWebpackPlugin (options) { /** * Warning: modifies the input object +======= +>>>>>>> origin * @param {Cypress.ConfigOptions} config * @param {WebpackOptions} options */ diff --git a/packages/example/README.md b/packages/example/README.md index a9f94349e587..8a36c6cd4150 100644 --- a/packages/example/README.md +++ b/packages/example/README.md @@ -1,9 +1,4 @@ - -## Scaffold config files - -The `cypress/plugins/index.js`, `cypress/support/*` and `cypress/tsconfig.json` from this package are used for user scaffolding in `packages/server` and `npm/create-cypress-tests`. This configuration files are by default injected when user instals Cypress. - -## Examples +## Example This repo contains the source code for pushing out [https://example.cypress.io](https://example.cypress.io). diff --git a/packages/example/bin/build.js b/packages/example/bin/build.js index 85454c6c3ea5..e46b80331f1e 100644 --- a/packages/example/bin/build.js +++ b/packages/example/bin/build.js @@ -11,8 +11,8 @@ shell.rm('-rf', 'app') shell.mkdir('app') shell.cp('-r', join(resolvePkg('cypress-example-kitchensink'), 'app'), '.') -shell.rm('-rf', 'cypress/integration') +shell.rm('-rf', 'cypress') -shell.cp('-r', join(resolvePkg('cypress-example-kitchensink'), 'cypress', 'integration'), 'cypress/integration') +shell.cp('-r', join(resolvePkg('cypress-example-kitchensink'), 'cypress'), '.') shell.exec('node ./bin/convert.js') diff --git a/packages/example/cypress/tsconfig.json b/packages/example/cypress/tsconfig.json deleted file mode 100644 index 4109e0ec1aff..000000000000 --- a/packages/example/cypress/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "compilerOptions": { - "target": "es5", - "lib": ["es5", "dom"], - "types": ["cypress"] - }, - "include": [ - "**/*.ts" - ] -} \ No newline at end of file diff --git a/packages/example/index.d.ts b/packages/example/index.d.ts deleted file mode 100644 index 6319bc5ceb03..000000000000 --- a/packages/example/index.d.ts +++ /dev/null @@ -1 +0,0 @@ -export { default } from './lib/example' \ No newline at end of file diff --git a/packages/example/lib/example.d.ts b/packages/example/lib/example.d.ts deleted file mode 100644 index 35ea4dbef283..000000000000 --- a/packages/example/lib/example.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -declare const example: { - getPathToExamples(): Promise; - getFolderName(): string; - getPathToPlugins(): string; - getPathToSupportFiles(): Promise; - getPathToTsConfig(): string; - getPathToFixture(): string; -} - -export default example; \ No newline at end of file diff --git a/packages/example/lib/example.js b/packages/example/lib/example.js index e5e95a541c1f..92fb5e0422b4 100644 --- a/packages/example/lib/example.js +++ b/packages/example/lib/example.js @@ -16,33 +16,8 @@ module.exports = { ) ) }, - + getFolderName () { return 'examples' }, - - getPathToPlugins() { - return path.resolve(__dirname, '..', 'cypress', 'plugins', 'index.js') - }, - - getPathToSupportFiles() { - return glob( - path.join( - __dirname, - '..', - 'cypress', - 'support', - '**', - '*' - ) - ) - }, - - getPathToTsConfig() { - return path.resolve(__dirname, '..', 'cypress', 'tsconfig.json') - }, - - getPathToFixture() { - return path.resolve(__dirname, '..', 'cypress', 'fixtures', 'example.json') - } } diff --git a/packages/example/package.json b/packages/example/package.json index f3dd921b24d9..c8da7bf9aea4 100644 --- a/packages/example/package.json +++ b/packages/example/package.json @@ -3,7 +3,6 @@ "version": "0.0.0", "private": true, "main": "index.js", - "types": "index.d.ts", "scripts": { "postinstall": "echo '@packages/example needs: yarn build'", "clean-deps": "rm -rf node_modules", diff --git a/packages/server/__snapshots__/scaffold_spec.js b/packages/server/__snapshots__/scaffold_spec.js index 371a2fb1e2f6..9aa72059d23e 100644 --- a/packages/server/__snapshots__/scaffold_spec.js +++ b/packages/server/__snapshots__/scaffold_spec.js @@ -342,11 +342,11 @@ exports['lib/scaffold .support creates supportFolder and commands.js and index.j // // // -- This is a child command -- -// Cypress.Commands.add("drag", { prevSubject: "element"}, (subject, options) => { ... }) +// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) // // // -- This is a dual command -- -// Cypress.Commands.add("dismiss", { prevSubject: "optional"}, (subject, options) => { ... }) +// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) // // // -- This will overwrite an existing command -- diff --git a/packages/server/lib/scaffold.js b/packages/server/lib/scaffold.js index 657ed7f56bad..8bbfbbbf8d2c 100644 --- a/packages/server/lib/scaffold.js +++ b/packages/server/lib/scaffold.js @@ -157,7 +157,7 @@ module.exports = { return this.verifyScaffolding(folder, () => { debug(`copying example.json into ${folder}`) - return this._copy(cypressEx.getPathToFixture(), folder, config) + return this._copy('fixtures/example.json', folder, config) }) }, @@ -172,14 +172,10 @@ module.exports = { return this.verifyScaffolding(folder, () => { debug(`copying commands.js and index.js to ${folder}`) - return cypressEx.getPathToSupportFiles() - .then((supportFiles) => { - return Promise.all( - supportFiles.map((supportFilePath) => { - return this._copy(supportFilePath, folder, config) - }), - ) - }) + return Promise.join( + this._copy('support/commands.js', folder, config), + this._copy('support/index.js', folder, config), + ) }) }, @@ -194,7 +190,7 @@ module.exports = { return this.verifyScaffolding(folder, () => { debug(`copying index.js into ${folder}`) - return this._copy(cypressEx.getPathToPlugins(), folder, config) + return this._copy('plugins/index.js', folder, config) }) }, diff --git a/packages/example/cypress/fixtures/example.json b/packages/server/lib/scaffold/fixtures/example.json similarity index 98% rename from packages/example/cypress/fixtures/example.json rename to packages/server/lib/scaffold/fixtures/example.json index 02e4254378e9..da18d9352a17 100644 --- a/packages/example/cypress/fixtures/example.json +++ b/packages/server/lib/scaffold/fixtures/example.json @@ -2,4 +2,4 @@ "name": "Using fixtures to represent data", "email": "hello@cypress.io", "body": "Fixtures are a great way to mock data for responses to routes" -} +} \ No newline at end of file diff --git a/packages/example/cypress/plugins/index.js b/packages/server/lib/scaffold/plugins/index.js similarity index 100% rename from packages/example/cypress/plugins/index.js rename to packages/server/lib/scaffold/plugins/index.js diff --git a/packages/example/cypress/support/commands.js b/packages/server/lib/scaffold/support/commands.js similarity index 84% rename from packages/example/cypress/support/commands.js rename to packages/server/lib/scaffold/support/commands.js index b39d4ca4954d..ca4d256f3eb1 100644 --- a/packages/example/cypress/support/commands.js +++ b/packages/server/lib/scaffold/support/commands.js @@ -14,11 +14,11 @@ // // // -- This is a child command -- -// Cypress.Commands.add("drag", { prevSubject: "element"}, (subject, options) => { ... }) +// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... }) // // // -- This is a dual command -- -// Cypress.Commands.add("dismiss", { prevSubject: "optional"}, (subject, options) => { ... }) +// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... }) // // // -- This will overwrite an existing command -- diff --git a/packages/example/cypress/support/index.js b/packages/server/lib/scaffold/support/index.js similarity index 100% rename from packages/example/cypress/support/index.js rename to packages/server/lib/scaffold/support/index.js diff --git a/packages/server/test/unit/scaffold_spec.js b/packages/server/test/unit/scaffold_spec.js index 12b9c8bdda03..ed5083d819a2 100644 --- a/packages/server/test/unit/scaffold_spec.js +++ b/packages/server/test/unit/scaffold_spec.js @@ -342,7 +342,7 @@ describe('lib/scaffold', () => { "name": "Using fixtures to represent data", "email": "hello@cypress.io", "body": "Fixtures are a great way to mock data for responses to routes" -} +}\ `) }) }) diff --git a/scripts/win-appveyor-build.js b/scripts/win-appveyor-build.js index 15a049c99436..e0f729a7dd8e 100755 --- a/scripts/win-appveyor-build.js +++ b/scripts/win-appveyor-build.js @@ -26,7 +26,7 @@ const isRightBranch = () => { process.env.APPVEYOR_REPO_COMMIT_MESSAGE || '' ).includes('[build binary]') - const branchesToBuildBinary = ['develop', 'v6.0-release'] + const branchesToBuildBinary = ['develop', 'revert-create-cypress-tests'] return branchesToBuildBinary.includes(branch) || shouldForceBinaryBuild } diff --git a/yarn.lock b/yarn.lock index c4cc31bafd3f..5516a8502511 100644 --- a/yarn.lock +++ b/yarn.lock @@ -213,28 +213,6 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/core@^7.5.4": - version "7.12.3" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.3.tgz#1b436884e1e3bff6fb1328dc02b208759de92ad8" - integrity sha512-0qXcZYKZp3/6N2jKYVxZv0aNCsxTSVCiK72DTiTYZAu7sjg73W0/aynWjMbiGd87EQL4WyA8reiJVh92AVla9g== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.12.1" - "@babel/helper-module-transforms" "^7.12.1" - "@babel/helpers" "^7.12.1" - "@babel/parser" "^7.12.3" - "@babel/template" "^7.10.4" - "@babel/traverse" "^7.12.1" - "@babel/types" "^7.12.1" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.1" - json5 "^2.1.2" - lodash "^4.17.19" - resolve "^1.3.2" - semver "^5.4.1" - source-map "^0.5.0" - "@babel/generator@^7.11.5", "@babel/generator@^7.11.6", "@babel/generator@^7.4.0", "@babel/generator@^7.4.4", "@babel/generator@^7.6.0", "@babel/generator@^7.9.0", "@babel/generator@^7.9.3": version "7.11.6" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.11.6.tgz#b868900f81b163b4d464ea24545c61cbac4dc620" @@ -244,15 +222,6 @@ jsesc "^2.5.1" source-map "^0.5.0" -"@babel/generator@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.1.tgz#0d70be32bdaa03d7c51c8597dda76e0df1f15468" - integrity sha512-DB+6rafIdc9o72Yc3/Ph5h+6hUjeOp66pF0naQBgUFFuPqzQwIlPTm3xZR7YNvduIMtkDIj2t21LSQwnbCrXvg== - dependencies: - "@babel/types" "^7.12.1" - jsesc "^2.5.1" - source-map "^0.5.0" - "@babel/generator@^7.12.5", "@babel/generator@^7.7.7": version "7.12.5" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.5.tgz#a2c50de5c8b6d708ab95be5e6053936c1884a4de" @@ -317,17 +286,6 @@ "@babel/helper-replace-supers" "^7.10.4" "@babel/helper-split-export-declaration" "^7.10.4" -"@babel/helper-create-class-features-plugin@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.12.1.tgz#3c45998f431edd4a9214c5f1d3ad1448a6137f6e" - integrity sha512-hkL++rWeta/OVOBTRJc9a5Azh5mt5WgZUGAKMD8JM141YsE08K//bp1unBBieO6rUKkIPyUE0USQ30jAy3Sk1w== - dependencies: - "@babel/helper-function-name" "^7.10.4" - "@babel/helper-member-expression-to-functions" "^7.12.1" - "@babel/helper-optimise-call-expression" "^7.10.4" - "@babel/helper-replace-supers" "^7.12.1" - "@babel/helper-split-export-declaration" "^7.10.4" - "@babel/helper-create-regexp-features-plugin@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.4.tgz#fdd60d88524659a0b6959c0579925e425714f3b8" @@ -384,13 +342,6 @@ dependencies: "@babel/types" "^7.11.0" -"@babel/helper-member-expression-to-functions@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.1.tgz#fba0f2fcff3fba00e6ecb664bb5e6e26e2d6165c" - integrity sha512-k0CIe3tXUKTRSoEx1LQEPFU9vRQfqHtl+kf8eNnDqb4AUJEy5pz6aIiog+YWtVm2jpggjS1laH68bPsR+KWWPQ== - dependencies: - "@babel/types" "^7.12.1" - "@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.8.3": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz#4c5c54be04bd31670a7382797d75b9fa2e5b5620" @@ -398,13 +349,6 @@ dependencies: "@babel/types" "^7.10.4" -"@babel/helper-module-imports@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.12.1.tgz#1644c01591a15a2f084dd6d092d9430eb1d1216c" - integrity sha512-ZeC1TlMSvikvJNy1v/wPIazCu3NdOwgYZLIkmIyAsGhqkNpiDoQQRmaCK8YP4Pq3GPTLPV9WXaPCJKvx06JxKA== - dependencies: - "@babel/types" "^7.12.1" - "@babel/helper-module-transforms@^7.10.1", "@babel/helper-module-transforms@^7.10.4", "@babel/helper-module-transforms@^7.11.0", "@babel/helper-module-transforms@^7.9.0": version "7.11.0" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.11.0.tgz#b16f250229e47211abdd84b34b64737c2ab2d359" @@ -418,21 +362,6 @@ "@babel/types" "^7.11.0" lodash "^4.17.19" -"@babel/helper-module-transforms@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz#7954fec71f5b32c48e4b303b437c34453fd7247c" - integrity sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w== - dependencies: - "@babel/helper-module-imports" "^7.12.1" - "@babel/helper-replace-supers" "^7.12.1" - "@babel/helper-simple-access" "^7.12.1" - "@babel/helper-split-export-declaration" "^7.11.0" - "@babel/helper-validator-identifier" "^7.10.4" - "@babel/template" "^7.10.4" - "@babel/traverse" "^7.12.1" - "@babel/types" "^7.12.1" - lodash "^4.17.19" - "@babel/helper-optimise-call-expression@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz#50dc96413d594f995a77905905b05893cd779673" @@ -473,16 +402,6 @@ "@babel/traverse" "^7.10.4" "@babel/types" "^7.10.4" -"@babel/helper-replace-supers@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.12.1.tgz#f15c9cc897439281891e11d5ce12562ac0cf3fa9" - integrity sha512-zJjTvtNJnCFsCXVi5rUInstLd/EIVNmIKA1Q9ynESmMBWPWd+7sdR+G4/wdu+Mppfep0XLyG2m7EBPvjCeFyrw== - dependencies: - "@babel/helper-member-expression-to-functions" "^7.12.1" - "@babel/helper-optimise-call-expression" "^7.10.4" - "@babel/traverse" "^7.12.1" - "@babel/types" "^7.12.1" - "@babel/helper-simple-access@^7.10.1", "@babel/helper-simple-access@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz#0f5ccda2945277a2a7a2d3a821e15395edcf3461" @@ -491,13 +410,6 @@ "@babel/template" "^7.10.4" "@babel/types" "^7.10.4" -"@babel/helper-simple-access@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz#32427e5aa61547d38eb1e6eaf5fd1426fdad9136" - integrity sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA== - dependencies: - "@babel/types" "^7.12.1" - "@babel/helper-skip-transparent-expression-wrappers@^7.11.0": version "7.11.0" resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.11.0.tgz#eec162f112c2f58d3af0af125e3bb57665146729" @@ -536,15 +448,6 @@ "@babel/traverse" "^7.10.4" "@babel/types" "^7.10.4" -"@babel/helpers@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.12.1.tgz#8a8261c1d438ec18cb890434df4ec768734c1e79" - integrity sha512-9JoDSBGoWtmbay98efmT2+mySkwjzeFeAL9BuWNoVQpkPFQF8SIIFUfY5os9u8wVzglzoiPRSW7cuJmBDUt43g== - dependencies: - "@babel/template" "^7.10.4" - "@babel/traverse" "^7.12.1" - "@babel/types" "^7.12.1" - "@babel/helpers@^7.7.4": version "7.12.5" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.12.5.tgz#1a1ba4a768d9b58310eda516c449913fe647116e" @@ -568,11 +471,6 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.5.tgz#c7ff6303df71080ec7a4f5b8c003c58f1cf51037" integrity sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q== -"@babel/parser@^7.12.1", "@babel/parser@^7.12.3": - version "7.12.3" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.3.tgz#a305415ebe7a6c7023b40b5122a0662d928334cd" - integrity sha512-kFsOS0IbsuhO5ojF8Hc8z/8vEIOkylVBrjiZUbLTE3XFe0Qi+uu6HjzQixkFaqr0ZPAMZcBVxEwmsnsLPZ2Xsw== - "@babel/parser@^7.12.7", "@babel/parser@^7.7.7": version "7.12.7" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.7.tgz#fee7b39fe809d0e73e5b25eecaf5780ef3d73056" @@ -877,13 +775,6 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-typescript@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.12.1.tgz#460ba9d77077653803c3dd2e673f76d66b4029e5" - integrity sha512-UZNEcCY+4Dp9yYRCAHrHDU+9ZXLYaY9MgBXSRLkB9WjYFRR6quJBumfVrEkUxrePPBwFcpWfNKXqVRQQtm7mMA== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-transform-arrow-functions@^7.10.4", "@babel/plugin-transform-arrow-functions@^7.2.0", "@babel/plugin-transform-arrow-functions@^7.8.3": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.10.4.tgz#e22960d77e697c74f41c501d44d73dbf8a6a64cd" @@ -1250,15 +1141,6 @@ "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-typescript" "^7.10.4" -"@babel/plugin-transform-typescript@^7.2.0": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.12.1.tgz#d92cc0af504d510e26a754a7dbc2e5c8cd9c7ab4" - integrity sha512-VrsBByqAIntM+EYMqSm59SiMEf7qkmI9dqMt6RbD/wlwueWmYcI0FFK5Fj47pP6DRZm+3teXjosKlwcZJ5lIMw== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.12.1" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-typescript" "^7.12.1" - "@babel/plugin-transform-unicode-escapes@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.10.4.tgz#feae523391c7651ddac115dae0a9d06857892007" @@ -1668,7 +1550,7 @@ dependencies: regenerator-runtime "^0.13.4" -"@babel/template@^7.10.4", "@babel/template@^7.4.0", "@babel/template@^7.4.4", "@babel/template@^7.5.4", "@babel/template@^7.6.0", "@babel/template@^7.8.6": +"@babel/template@^7.10.4", "@babel/template@^7.4.0", "@babel/template@^7.4.4", "@babel/template@^7.6.0", "@babel/template@^7.8.6": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.4.tgz#3251996c4200ebc71d1a8fc405fba940f36ba278" integrity sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA== @@ -1701,25 +1583,10 @@ globals "^11.1.0" lodash "^4.17.19" -"@babel/traverse@^7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.1.tgz#941395e0c5cc86d5d3e75caa095d3924526f0c1e" - integrity sha512-MA3WPoRt1ZHo2ZmoGKNqi20YnPt0B1S0GTZEPhhd+hw2KGUzBlHuVunj6K4sNuK+reEvyiPwtp0cpaqLzJDmAw== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.12.1" - "@babel/helper-function-name" "^7.10.4" - "@babel/helper-split-export-declaration" "^7.11.0" - "@babel/parser" "^7.12.1" - "@babel/types" "^7.12.1" - debug "^4.1.0" - globals "^11.1.0" - lodash "^4.17.19" - "@babel/traverse@^7.12.5", "@babel/traverse@^7.7.4": - version "7.12.8" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.8.tgz#c1c2983bf9ba0f4f0eaa11dff7e77fa63307b2a4" - integrity sha512-EIRQXPTwFEGRZyu6gXbjfpNORN1oZvwuzJbxcXjAgWV0iqXYDszN1Hx3FVm6YgZfu1ZQbCVAk3l+nIw95Xll9Q== + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.7.tgz#572a722408681cef17d6b0bef69ef2e728ca69f1" + integrity sha512-nMWaqsQEeSvMNypswUDzjqQ+0rR6pqCtoQpsqGJC4/Khm9cISwPTSpai57F6/jDaOoEGz8yE/WxcO3PV6tKSmQ== dependencies: "@babel/code-frame" "^7.10.4" "@babel/generator" "^7.12.5" @@ -1749,15 +1616,6 @@ lodash "^4.17.13" to-fast-properties "^2.0.0" -"@babel/types@^7.12.1", "@babel/types@^7.5.0": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.1.tgz#e109d9ab99a8de735be287ee3d6a9947a190c4ae" - integrity sha512-BzSY3NJBKM4kyatSOWh3D/JJ2O3CVzBybHWxtgxnggaxEuaSTTDqeiSb/xk9lrkw2Tbqyivw5ZU4rT+EfznQsA== - dependencies: - "@babel/helper-validator-identifier" "^7.10.4" - lodash "^4.17.19" - to-fast-properties "^2.0.0" - "@babel/types@^7.12.5", "@babel/types@^7.12.7", "@babel/types@^7.7.4": version "7.12.7" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.7.tgz#6039ff1e242640a29452c9ae572162ec9a8f5d13" @@ -5148,17 +5006,6 @@ "@types/babel__template" "*" "@types/babel__traverse" "*" -"@types/babel__core@^7.1.2": - version "7.1.11" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.11.tgz#7fae4660a009a4031e293f25b213f142d823b3c4" - integrity sha512-E5nSOzrjnvhURYnbOR2dClTqcyhPbPvtEwLHf7JJADKedPbcZsoJVfP+I2vBNfBjz4bnZIuhL/tNmRi5nJ7Jlw== - dependencies: - "@babel/parser" "^7.1.0" - "@babel/types" "^7.0.0" - "@types/babel__generator" "*" - "@types/babel__template" "*" - "@types/babel__traverse" "*" - "@types/babel__generator@*": version "7.6.1" resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.1.tgz#4901767b397e8711aeb99df8d396d7ba7b7f0e04" @@ -5627,13 +5474,6 @@ resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA== -"@types/ora@^3.2.0": - version "3.2.0" - resolved "https://registry.yarnpkg.com/@types/ora/-/ora-3.2.0.tgz#b2f65d1283a8f36d8b0f9ee767e0732a2f429362" - integrity sha512-jll99xUKpiFbIFZSQcxm4numfsLaOWBzWNaRk3PvTSE7BPqTzzOCFmS0mQ7m8qkTfmYhuYbehTGsxkvRLPC++w== - dependencies: - ora "*" - "@types/parse-json@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" @@ -8871,7 +8711,7 @@ bindings@^1.5.0: dependencies: file-uri-to-path "1.0.0" -bl@^4.0.3: +bl@^4.0.1, bl@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/bl/-/bl-4.0.3.tgz#12d6287adc29080e22a705e5764b2a9522cdc489" integrity sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg== @@ -9951,9 +9791,9 @@ caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30000989, can integrity sha512-EHfInJHoQTmlMdVZrEc5gmwPc0zyN/hVufmGHPbVNQwlk7tJfCmQ2ysRZMY2MeleBivALUTyyxXnQjK18XrVpA== caniuse-lite@^1.0.30001093, caniuse-lite@^1.0.30001113: - version "1.0.30001161" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001161.tgz#64f7ffe79ee780b8c92843ff34feb36cea4651e0" - integrity sha512-JharrCDxOqPLBULF9/SPa6yMcBRTjZARJ6sc3cuKrPfyIk64JN6kuMINWqA99Xc8uElMFcROliwtz0n9pYej+g== + version "1.0.30001159" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001159.tgz#bebde28f893fa9594dadcaa7d6b8e2aa0299df20" + integrity sha512-w9Ph56jOsS8RL20K9cLND3u/+5WASWdhC/PPrf+V3/HsM3uHOavWOR1Xzakbv4Puo/srmPHudkmCRWM7Aq+/UA== capture-exit@^2.0.0: version "2.0.0" @@ -10068,7 +9908,7 @@ chai@4.2.0: pathval "^1.1.0" type-detect "^4.0.5" -chalk@*, chalk@4.1.0, chalk@^4.0.0, chalk@^4.1.0: +chalk@*, chalk@^4.0.0, chalk@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== @@ -10538,23 +10378,6 @@ cli-cursor@^3.1.0: dependencies: restore-cursor "^3.1.0" -cli-highlight@2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/cli-highlight/-/cli-highlight-2.1.4.tgz#098cb642cf17f42adc1c1145e07f960ec4d7522b" - integrity sha512-s7Zofobm20qriqDoU9sXptQx0t2R9PEgac92mENNm7xaEe1hn71IIMsXMK+6encA6WRCWWxIGQbipr3q998tlQ== - dependencies: - chalk "^3.0.0" - highlight.js "^9.6.0" - mz "^2.4.0" - parse5 "^5.1.1" - parse5-htmlparser2-tree-adapter "^5.1.1" - yargs "^15.0.0" - -cli-spinners@^2.4.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.5.0.tgz#12763e47251bf951cb75c201dfa58ff1bcb2d047" - integrity sha512-PC+AmIuK04E6aeSs/pUccSujsTzBhu4HzC2dL+CfJB/Jcc2qTRbEwZQDfIUpt2Xl8BodYBEq8w4fc0kU2I9DjQ== - cli-table3@0.5.1, cli-table3@^0.5.0, cli-table3@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.5.1.tgz#0252372d94dfc40dbd8df06005f48f31f656f202" @@ -11008,11 +10831,6 @@ commander@2.x.x, commander@^2.11.0, commander@^2.12.1, commander@^2.13.0, comman resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== -commander@6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-6.1.0.tgz#f8d722b78103141006b66f4c7ba1e97315ba75bc" - integrity sha512-wl7PNrYWd2y5mp1OK/LhTlv8Ff4kQJQRXXAvF+uU/TPNiVJUxZLRYGj/B0y/lPGAVcSbJqH2Za/cvHmrPMC8mA== - commander@^4.0.1, commander@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" @@ -13580,9 +13398,9 @@ electron-to-chromium@^1.3.247, electron-to-chromium@^1.3.378, electron-to-chromi integrity sha512-uSEI0XZ//5ic+0NdOqlxp0liCD44ck20OAGyLMSymIWTEAtHKVJi6JM18acOnRgUgX7Q65QqnI+sNncNvIy8ew== electron-to-chromium@^1.3.488: - version "1.3.606" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.606.tgz#6ef2655d9a7c1b447dfdd6344657d00461a65e26" - integrity sha512-+/2yPHwtNf6NWKpaYt0KoqdSZ6Qddt6nDfH/pnhcrHq9hSb23e5LFy06Mlf0vF2ykXvj7avJ597psqcbKnG5YQ== + version "1.3.603" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.603.tgz#1b71bec27fb940eccd79245f6824c63d5f7e8abf" + integrity sha512-J8OHxOeJkoSLgBXfV9BHgKccgfLMHh+CoeRo6wJsi6m0k3otaxS/5vrHpMNSEYY4MISwewqanPOuhAtuE8riQQ== electron@11.0.2: version "11.0.2" @@ -17343,11 +17161,6 @@ highlight.js@^8.5.0: resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-8.9.1.tgz#b8a9c5493212a9392f0222b649c9611497ebfb88" integrity sha1-uKnFSTISqTkvAiK2SclhFJfr+4g= -highlight.js@^9.6.0: - version "9.18.5" - resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.18.5.tgz#d18a359867f378c138d6819edfc2a8acd5f29825" - integrity sha512-a5bFyofd/BHCX52/8i8uJkjr9DYwXIPnM/plwI6W7ezItLGqzt7X2G2nXuYSfsIJdkwwj/g9DG1LkcGJI/dDoA== - history@5.0.0-beta.4: version "5.0.0-beta.4" resolved "https://registry.yarnpkg.com/history/-/history-5.0.0-beta.4.tgz#7fd3bb1f6c75d00d9b5112a816766bfc72d1a3cd" @@ -18162,25 +17975,6 @@ inquirer@7.0.4: strip-ansi "^5.1.0" through "^2.3.6" -inquirer@7.3.3, inquirer@^7.0.0: - version "7.3.3" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.3.3.tgz#04d176b2af04afc157a83fd7c100e98ee0aad003" - integrity sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA== - dependencies: - ansi-escapes "^4.2.1" - chalk "^4.1.0" - cli-cursor "^3.1.0" - cli-width "^3.0.0" - external-editor "^3.0.3" - figures "^3.0.0" - lodash "^4.17.19" - mute-stream "0.0.8" - run-async "^2.4.0" - rxjs "^6.6.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - through "^2.3.6" - inquirer@^6.2.0: version "6.5.2" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.2.tgz#ad50942375d036d327ff528c08bd5fab089928ca" @@ -18200,6 +17994,25 @@ inquirer@^6.2.0: strip-ansi "^5.1.0" through "^2.3.6" +inquirer@^7.0.0: + version "7.3.3" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.3.3.tgz#04d176b2af04afc157a83fd7c100e98ee0aad003" + integrity sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA== + dependencies: + ansi-escapes "^4.2.1" + chalk "^4.1.0" + cli-cursor "^3.1.0" + cli-width "^3.0.0" + external-editor "^3.0.3" + figures "^3.0.0" + lodash "^4.17.19" + mute-stream "0.0.8" + run-async "^2.4.0" + rxjs "^6.6.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + through "^2.3.6" + insert-module-globals@^7.0.0: version "7.2.0" resolved "https://registry.yarnpkg.com/insert-module-globals/-/insert-module-globals-7.2.0.tgz#ec87e5b42728479e327bd5c5c71611ddfb4752ba" @@ -18604,11 +18417,6 @@ is-integer@^1.0.4: dependencies: is-finite "^1.0.0" -is-interactive@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" - integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== - is-map@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.1.tgz#520dafc4307bb8ebc33b813de5ce7c9400d644a1" @@ -24121,20 +23929,6 @@ optionator@^0.8.1, optionator@^0.8.2, optionator@^0.8.3: type-check "~0.3.2" word-wrap "~1.2.3" -ora@*, ora@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/ora/-/ora-5.1.0.tgz#b188cf8cd2d4d9b13fd25383bc3e5cba352c94f8" - integrity sha512-9tXIMPvjZ7hPTbk8DFq1f7Kow/HU/pQYB60JbNq+QnGwcyhWVZaQ4hM9zQDEsPxw/muLpgiHSaumUZxCAmod/w== - dependencies: - chalk "^4.1.0" - cli-cursor "^3.1.0" - cli-spinners "^2.4.0" - is-interactive "^1.0.0" - log-symbols "^4.0.0" - mute-stream "0.0.8" - strip-ansi "^6.0.0" - wcwidth "^1.0.1" - ordered-read-streams@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz#77c0cb37c41525d64166d990ffad7ec6a0e1363e" @@ -24707,13 +24501,6 @@ parse5-html-rewriting-stream@5.1.1: parse5 "^5.1.1" parse5-sax-parser "^5.1.1" -parse5-htmlparser2-tree-adapter@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-5.1.1.tgz#e8c743d4e92194d5293ecde2b08be31e67461cbc" - integrity sha512-CF+TKjXqoqyDwHqBhFQ+3l5t83xYi6fVT1tQNg+Ye0JRLnTxWvIroCjEp1A0k4lneHNBGnICUf0cfYVYGEazqw== - dependencies: - parse5 "^5.1.1" - parse5-sax-parser@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/parse5-sax-parser/-/parse5-sax-parser-5.1.1.tgz#02834a9d08b23ea2d99584841c38be09d5247a15" @@ -30923,7 +30710,18 @@ tar-fs@^2.0.0: pump "^3.0.0" tar-stream "^2.0.0" -tar-stream@^2.0.0, tar-stream@^2.1.4: +tar-stream@^2.0.0: + version "2.1.3" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.1.3.tgz#1e2022559221b7866161660f118255e20fa79e41" + integrity sha512-Z9yri56Dih8IaK8gncVPx4Wqt86NDmQTSh49XLZgjWpGZL9GK9HKParS2scqHCC4w6X9Gh2jwaU45V47XTKwVA== + dependencies: + bl "^4.0.1" + end-of-stream "^1.4.1" + fs-constants "^1.0.0" + inherits "^2.0.3" + readable-stream "^3.1.1" + +tar-stream@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.1.4.tgz#c4fb1a11eb0da29b893a5b25476397ba2d053bfa" integrity sha512-o3pS2zlG4gxr67GmFYBLlq+dM8gyRGUOvsrHclSkvtVtQbjV0s/+ZE8OpICbaj8clrX3tjeHngYGP7rweaBnuw== @@ -33144,7 +32942,7 @@ wbuf@^1.1.0, wbuf@^1.7.3: dependencies: minimalistic-assert "^1.0.0" -wcwidth@^1.0.0, wcwidth@^1.0.1: +wcwidth@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g= @@ -34530,7 +34328,7 @@ yargs@^14.2.2, yargs@^14.2.3: y18n "^4.0.0" yargs-parser "^15.0.1" -yargs@^15.0.0, yargs@^15.0.1, yargs@^15.0.2, yargs@^15.3.1: +yargs@^15.0.1, yargs@^15.0.2, yargs@^15.3.1: version "15.4.1" resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8" integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==