diff --git a/.gitattributes b/.gitattributes index 04179d5018a4..ebbd9782ff01 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,5 @@ * text=auto *.json text eol=lf + +packages/errors/__snapshot-html__/** linguist-generated=true \ No newline at end of file diff --git a/.gitignore b/.gitignore index 73f60d64cc5b..681c0c659c74 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,8 @@ Cached Theme Material Design.pak # from data-context, compiled .js files packages/data-context/src/**/*.js +packages/errors/src/**/*.js +packages/errors/test/**/*.js # from driver packages/driver/cypress/videos @@ -61,6 +63,7 @@ packages/socket/lib/*.js # from system-tests system-tests/.projects +system-tests/.http-mitm-proxy system-tests/fixtures/large-img # from npm/react @@ -76,6 +79,11 @@ system-tests/fixtures/large-img # from runner-ct /packages/runner-ct/cypress/screenshots +# from errors +/packages/errors/__snapshot-images__ +/packages/errors/__snapshot-md__ +/packages/errors/__snapshot-html-local__ + # graphql, auto-generated /packages/launchpad/src/generated /packages/app/src/generated diff --git a/.vscode/settings.json b/.vscode/settings.json index 5cee784b1cea..f2baf4638404 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -36,6 +36,7 @@ "i18n-ally.keystyle": "nested", // Volar is the main extension that powers Vue's language features. - "volar.autoCompleteRefs": false, + // These are commented out because they slow down node development + // "volar.autoCompleteRefs": false, // "volar.takeOverMode.enabled": true } diff --git a/.vscode/terminals.json b/.vscode/terminals.json index ff9b90c60008..e154b4233b49 100644 --- a/.vscode/terminals.json +++ b/.vscode/terminals.json @@ -53,6 +53,13 @@ "cwd": "[cwd]/packages/app", "command": "yarn dev" }, + { + "name": "packages/app watch", + "focus": true, + "onlySingle": true, + "cwd": "[cwd]", + "command": "yarn watch" + }, { "name": "packages/server test-watch", "focus": true, diff --git a/browser-versions.json b/browser-versions.json index 4e3334648db7..beec05263965 100644 --- a/browser-versions.json +++ b/browser-versions.json @@ -1,4 +1,4 @@ { - "chrome:beta": "98.0.4758.80", + "chrome:beta": "99.0.4844.27", "chrome:stable": "98.0.4758.80" } diff --git a/circle.yml b/circle.yml index cdf8e3a8038b..5dbf4c7dc1a9 100644 --- a/circle.yml +++ b/circle.yml @@ -1002,6 +1002,7 @@ jobs: - run: name: Linting 🧹 command: | + yarn clean git clean -df yarn lint - run: @@ -1120,12 +1121,14 @@ jobs: # run type checking for each individual package - run: yarn lerna run types - verify-mocha-results: - expectedResultCount: 9 + expectedResultCount: 10 - store_test_results: path: /tmp/cypress # CLI tests generate HTML files with sample CLI command output - store_artifacts: path: cli/test/html + - store_artifacts: + path: packages/errors/__snapshot-images__ - store-npm-logs unit-tests-release: @@ -1983,14 +1986,6 @@ jobs: browser: "electron" pull_request_id: 524 - test-binary-against-awesome-typescript-loader: - <<: *defaults - steps: - - test-binary-against-repo: - repo: cypress-test-awesome-typescript-loader - browser: "electron" - pull_request_id: 8 - test-binary-against-kitchensink-firefox: <<: *defaults resource_class: medium @@ -2334,26 +2329,6 @@ linux-workflow: &linux-workflow - test-binary-against-kitchensink: requires: - create-build-artifacts - # when working on a feature or a fix, - # you are probably working in a branch - # and you want to run a specific PR in the cypress-example-recipes - # against this branch. This workflow job includes - # the job but only when it runs on specific branch - # DO NOT DELETE THIS JOB BEFORE MERGING TO DEVELOP - # on "develop" this branch will be ignored anyway - # and someone else might use this job definition for another - # feature branch and would just update the branch filter - # - test-binary-against-recipe-pull-request: - # name: Test cypress run parsing - # filters: - # branches: - # only: - # - cli-to-module-api-7760 - # requires: - # - create-build-artifacts - - test-binary-against-awesome-typescript-loader: - requires: - - create-build-artifacts - test-binary-and-npm-against-other-projects: context: test-runner:trigger-test-jobs <<: *mainBuildFilters diff --git a/guides/error-handling.md b/guides/error-handling.md new file mode 100644 index 000000000000..adcb79cb087f --- /dev/null +++ b/guides/error-handling.md @@ -0,0 +1,84 @@ +## Error Handling in Cypress + +Clear, consistent, errors are one of the important parts of the Cypress experience. When something goes wrong, there should be clear, actionable feedback for the user about exactly *what* went wrong, *where* it went wrong, and next steps on how to fix. + +### @packages/errors + +All error related logic for the server should be added to `@packages/errors`. This logic has been separated out from the `@packages/server` to enable strict type checking & use in other packages we have added in the `10.0-release` branch. + +Summary of the Errors package: + +- `errors.ts`: A key/value mapping of known errors to functions returning "ErrorTemplates", described below, also includes/re-exports several helper utilities: + - `get` / `getError`: builds & retrieves the error as a `CypressError`, should be the main way we retrieve errors throughout Cypress. Aliased as `errors.get` for existing use in the server package + - `throw` / `throwErr`: Get & throw the error, so we can spy/stub it in a test. Aliased as `errors.throwErr` for existing use in the server package + - `logWarning`: Logs the error as a warning to the console, aliased as `errors.log` for existing use in the server package +- `errTemplate.ts`: Tagged template literal formatting the error as described below +- `stackUtils.ts`: Utilities for working with a stack trace, extended by the driver package + +### errTemplate + +The `errTemplate` is a tagged template literal. It allows us to maintain consistent behavior & formatting in our error messages, when we see a variable, we format it depending on the target environment. + +The error message returns a message that defaults to being formatted for the terminal, and has a `forBrowser` method which returns the error message where the variables are wrapped in backticks '`' for Markdown display in the browser. + +Return Value of `errTemplate` (`ErrTemplateResult`): + +```ts +{ + // Will always exist, this is the terminal-formatted error message + message: string, + // Will always exist, this is the browser-formatted error message + messageMarkdown: string, + details?: string, // Exists if there is `details()` call in the errTemplate + originalError?: ErrorLike // Exists if an error was passed into the `details()` +} +``` + +#### Example: + +```ts +CANNOT_TRASH_ASSETS: (arg1: string) => { + return errTemplate`\ + Warning: We failed to trash the existing run results. + + This error will not alter the exit code. + + ${details(arg1)}` +}, +``` + +In this case, `arg1` will be highlighted in yellow when printed to the terminal. + + +```ts +PLUGINS_FILE_ERROR: (arg1: string, arg2: Error) => { + return errTemplate`\ + The plugins file is missing or invalid. + + Your \`pluginsFile\` is set to ${arg1}, but either the file is missing, it contains a syntax error, or threw an error when required. The \`pluginsFile\` must be a \`.js\`, \`.ts\`, or \`.coffee\` file. + + Or you might have renamed the extension of your \`pluginsFile\`. If that's the case, restart the test runner. + + Please fix this, or set \`pluginsFile\` to \`false\` if a plugins file is not necessary for your project. + + ${details(arg2)} + ` +}, +``` + +`arg1` will be highlighted in `blue` for the terminal, and wrapped in backticks when called with `forBrowser`. Details will be printed in `yellow` as a stack trace when printed to the terminal, or shown as a stack-trace in the browser. + +### Error Wrapping + +Any time we know about an edge case that is an error, we should define an error in `errors.ts`. This error should be retrieved by `getError`, which converts it to a `CypressError`. + +The `CypressError` is an `Error` containing the message returned from the `errTemplate`. The `stack` is set to that of the `originalError` if it exists (i.e. the error object passed into `details`), otherwise it's the `stack` from where the `getError` / `throwError` is called. + + +The `CypressError` has an `isCypressErr` prop which we use as a duck-type guard against exiting the process when logging exceptions. It also maintains a reference to the `originalError` if it exists. + +### Child-Process Errors + +All errors that occur in a child process spawned by Cypress should be sent over the `ipc` bridge using `util.serializeError`. + +This ensures the `name`, `message`, `stack`, and any other relevant details are preserved and can be handled by the standard process of Cypress' error standardization / wrapping. 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 index e6c7d58f91c9..d336b3fedef7 100644 --- 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 @@ -307,7 +307,7 @@ describe('init component tests script', () => { ).to.be.true }) - it('Doesn\'t affect injected code if user has custom babel.config.js', async () => { + it(`Doesn't affect injected code if user has custom babel.config.js`, async () => { createTempFiles({ '/cypress/plugins/index.js': 'module.exports = (on, config) => {}', '/cypress.config.ts': 'export default {}', diff --git a/npm/react/examples/nextjs/cypress/components/Page.cy.jsx b/npm/react/examples/nextjs/cypress/components/Page.cy.jsx index 879f84da6242..27f1a0dc6bfb 100644 --- a/npm/react/examples/nextjs/cypress/components/Page.cy.jsx +++ b/npm/react/examples/nextjs/cypress/components/Page.cy.jsx @@ -12,7 +12,7 @@ describe('NextJS page', () => { cy.contains('.search-text', 'You are searching for: Cypress') }) - it('It doesn\'t run the `.getInitialProps()`', () => { + it(`It doesn't run the .getInitialProps()`, () => { mount() cy.get('[data-testid="server-result"').should('not.exist') diff --git a/npm/vite-dev-server/src/makeCypressPlugin.ts b/npm/vite-dev-server/src/makeCypressPlugin.ts index b0b5ae85aed6..a0117d1e7fdc 100644 --- a/npm/vite-dev-server/src/makeCypressPlugin.ts +++ b/npm/vite-dev-server/src/makeCypressPlugin.ts @@ -55,7 +55,6 @@ export const makeCypressPlugin = ( base = config.base }, async transformIndexHtml () { - debug('transformIndexHtml with base', base) const indexHtmlPath = indexHtml ? resolve(projectRoot, indexHtml) : resolve(__dirname, '..', 'index.html') const indexHtmlContent = await readFile(indexHtmlPath, { encoding: 'utf8' }) // find last index diff --git a/npm/vite-dev-server/src/resolveServerConfig.ts b/npm/vite-dev-server/src/resolveServerConfig.ts index ef1a3a6df1da..89d0b94ca047 100644 --- a/npm/vite-dev-server/src/resolveServerConfig.ts +++ b/npm/vite-dev-server/src/resolveServerConfig.ts @@ -1,5 +1,5 @@ import Debug from 'debug' -import { createServer, ViteDevServer, InlineConfig } from 'vite' +import { InlineConfig } from 'vite' import { dirname, resolve } from 'path' import getPort from 'get-port' import { makeCypressPlugin } from './makeCypressPlugin' diff --git a/package.json b/package.json index 2931a00e43c7..d4cea2eb2f9b 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "bump": "node ./scripts/binary.js bump", "check-node-version": "node scripts/check-node-version.js", "check-terminal": "node scripts/check-terminal.js", - "clean": "lerna run clean --parallel --no-bail", + "clean": "lerna run clean --parallel --no-bail || echo 'ok, errors while cleaning'", "check-ts": "gulp checkTs", "clean-deps": "find . -depth -name node_modules -type d -exec rm -rf {} \\;", "clean-untracked-files": "git clean -d -f", @@ -28,6 +28,7 @@ "cypress:open:debug": "node ./scripts/debug.js cypress:open", "precypress:run": "yarn ensure-deps", "cypress:run": "cypress run --dev", + "cypress:run:ct": "cypress run-ct --dev", "precypress:run:debug": "yarn ensure-deps", "cypress:run:debug": "node ./scripts/debug.js cypress:run", "cypress:verify": "cypress verify --dev", @@ -50,7 +51,7 @@ "stop-only": "npx stop-only --skip .cy,.publish,.projects,node_modules,dist,dist-test,fixtures,lib,bower_components,src,__snapshots__ --exclude cypress-tests.ts,*only.cy.js", "stop-only-all": "yarn stop-only --folder packages", "pretest": "yarn ensure-deps", - "test": "yarn lerna exec yarn test --scope cypress --scope \"'@packages/{config,data-context,electron,extension,https-proxy,launcher,net-stubbing,network,proxy,rewriter,socket}'\"", + "test": "yarn lerna exec yarn test --scope cypress --scope \"'@packages/{config,errors,data-context,electron,extension,https-proxy,launcher,net-stubbing,network,proxy,rewriter,socket}'\"", "test-debug": "lerna exec yarn test-debug --ignore \"'@packages/{driver,root,static,web-config}'\"", "pretest-e2e": "yarn ensure-deps", "test-integration": "lerna exec yarn test-integration --ignore \"'@packages/{driver,root,static,web-config}'\"", @@ -125,7 +126,6 @@ "@typescript-eslint/eslint-plugin": "4.18.0", "@typescript-eslint/parser": "4.18.0", "@urql/introspection": "^0.3.0", - "ansi-styles": "3.2.1", "arg": "4.1.2", "ascii-table": "0.0.9", "autobarrel": "^1.1.0", @@ -213,7 +213,7 @@ "snap-shot-it": "7.9.3", "start-server-and-test": "1.10.8", "stop-only": "3.0.1", - "strip-ansi": "4.0.0", + "strip-ansi": "6.0.0", "term-to-html": "1.2.0", "terminal-banner": "1.1.0", "through": "2.3.8", diff --git a/packages/config/__snapshots__/validation_spec.js b/packages/config/__snapshots__/validation_spec.js index 538d5d145fa1..0f0171ed3ca9 100644 --- a/packages/config/__snapshots__/validation_spec.js +++ b/packages/config/__snapshots__/validation_spec.js @@ -6,9 +6,12 @@ exports['empty list of browsers'] = ` Expected at least one browser ` -exports['browsers list with a string'] = ` -Found an error while validating the \`browsers\` list. Expected \`name\` to be a non-empty string. Instead the value was: \`"foo"\` -` +exports['browsers list with a string'] = { + "key": "name", + "value": "foo", + "type": "a non-empty string", + "list": "browsers" +} exports['src/validation .isValidBrowser passes valid browsers and forms error messages for invalid ones isValidBrowser 1'] = { "name": "isValidBrowser", @@ -51,7 +54,14 @@ exports['src/validation .isValidBrowser passes valid browsers and forms error me "name": "No display name", "family": "chromium" }, - "expect": "Expected `displayName` to be a non-empty string. Instead the value was: `{\"name\":\"No display name\",\"family\":\"chromium\"}`" + "expect": { + "key": "displayName", + "value": { + "name": "No display name", + "family": "chromium" + }, + "type": "a non-empty string" + } }, { "given": { @@ -59,99 +69,158 @@ exports['src/validation .isValidBrowser passes valid browsers and forms error me "displayName": "Bad family browser", "family": "unknown family" }, - "expect": "Expected `family` to be either chromium or firefox. Instead the value was: `{\"name\":\"bad family\",\"displayName\":\"Bad family browser\",\"family\":\"unknown family\"}`" + "expect": { + "key": "family", + "value": { + "name": "bad family", + "displayName": "Bad family browser", + "family": "unknown family" + }, + "type": "either chromium or firefox" + } } ] } -exports['not one of the strings error message'] = ` -Expected \`test\` to be one of these values: "foo", "bar". Instead the value was: \`"nope"\` -` +exports['not one of the strings error message'] = { + "key": "test", + "value": "nope", + "type": "one of these values: \"foo\", \"bar\"" +} -exports['number instead of string'] = ` -Expected \`test\` to be one of these values: "foo", "bar". Instead the value was: \`42\` -` +exports['number instead of string'] = { + "key": "test", + "value": 42, + "type": "one of these values: \"foo\", \"bar\"" +} -exports['null instead of string'] = ` -Expected \`test\` to be one of these values: "foo", "bar". Instead the value was: \`null\` -` +exports['null instead of string'] = { + "key": "test", + "value": null, + "type": "one of these values: \"foo\", \"bar\"" +} -exports['not one of the numbers error message'] = ` -Expected \`test\` to be one of these values: 1, 2, 3. Instead the value was: \`4\` -` +exports['not one of the numbers error message'] = { + "key": "test", + "value": 4, + "type": "one of these values: 1, 2, 3" +} -exports['string instead of a number'] = ` -Expected \`test\` to be one of these values: 1, 2, 3. Instead the value was: \`"foo"\` -` +exports['string instead of a number'] = { + "key": "test", + "value": "foo", + "type": "one of these values: 1, 2, 3" +} -exports['null instead of a number'] = ` -Expected \`test\` to be one of these values: 1, 2, 3. Instead the value was: \`null\` -` +exports['null instead of a number'] = { + "key": "test", + "value": null, + "type": "one of these values: 1, 2, 3" +} -exports['src/validation .isStringOrFalse returns error message when value is neither string nor false 1'] = ` -Expected \`mockConfigKey\` to be a string or false. Instead the value was: \`null\` -` +exports['src/validation .isStringOrFalse returns error message when value is neither string nor false 1'] = { + "key": "mockConfigKey", + "value": null, + "type": "a string or false" +} -exports['src/validation .isBoolean returns error message when value is a not a string 1'] = ` -Expected \`mockConfigKey\` to be a string. Instead the value was: \`1\` -` +exports['src/validation .isBoolean returns error message when value is a not a string 1'] = { + "key": "mockConfigKey", + "value": 1, + "type": "a string" +} -exports['src/validation .isString returns error message when value is a not a string 1'] = ` -Expected \`mockConfigKey\` to be a string. Instead the value was: \`1\` -` +exports['src/validation .isString returns error message when value is a not a string 1'] = { + "key": "mockConfigKey", + "value": 1, + "type": "a string" +} -exports['src/validation .isArray returns error message when value is a non-array 1'] = ` -Expected \`mockConfigKey\` to be an array. Instead the value was: \`1\` -` +exports['src/validation .isArray returns error message when value is a non-array 1'] = { + "key": "mockConfigKey", + "value": 1, + "type": "an array" +} -exports['not string or array'] = ` -Expected \`mockConfigKey\` to be a string or an array of strings. Instead the value was: \`null\` -` +exports['not string or array'] = { + "key": "mockConfigKey", + "value": null, + "type": "a string or an array of strings" +} -exports['array of non-strings'] = ` -Expected \`mockConfigKey\` to be a string or an array of strings. Instead the value was: \`[1,2,3]\` -` +exports['array of non-strings'] = { + "key": "mockConfigKey", + "value": [ + 1, + 2, + 3 + ], + "type": "a string or an array of strings" +} -exports['src/validation .isNumberOrFalse returns error message when value is a not number or false 1'] = ` -Expected \`mockConfigKey\` to be a number or false. Instead the value was: \`null\` -` +exports['src/validation .isNumberOrFalse returns error message when value is a not number or false 1'] = { + "key": "mockConfigKey", + "value": null, + "type": "a number or false" +} -exports['src/validation .isPlainObject returns error message when value is a not an object 1'] = ` -Expected \`mockConfigKey\` to be a plain object. Instead the value was: \`1\` -` +exports['src/validation .isPlainObject returns error message when value is a not an object 1'] = { + "key": "mockConfigKey", + "value": 1, + "type": "a plain object" +} -exports['src/validation .isNumber returns error message when value is a not a number 1'] = ` -Expected \`mockConfigKey\` to be a number. Instead the value was: \`"string"\` -` +exports['src/validation .isNumber returns error message when value is a not a number 1'] = { + "key": "mockConfigKey", + "value": "string", + "type": "a number" +} -exports['invalid retry value'] = ` -Expected \`mockConfigKey\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls. Instead the value was: \`"1"\` -` +exports['invalid retry value'] = { + "key": "mockConfigKey", + "value": "1", + "type": "a positive number or null or an object with keys \"openMode\" and \"runMode\" with values of numbers or nulls" +} -exports['invalid retry object'] = ` -Expected \`mockConfigKey\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls. Instead the value was: \`{"fakeMode":1}\` -` +exports['invalid retry object'] = { + "key": "mockConfigKey", + "value": { + "fakeMode": 1 + }, + "type": "a positive number or null or an object with keys \"openMode\" and \"runMode\" with values of numbers or nulls" +} -exports['src/validation .isValidClientCertificatesSet returns error message for certs not passed as an array array 1'] = ` -Expected \`mockConfigKey\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls. Instead the value was: \`"1"\` -` +exports['src/validation .isValidClientCertificatesSet returns error message for certs not passed as an array array 1'] = { + "key": "mockConfigKey", + "value": "1", + "type": "a positive number or null or an object with keys \"openMode\" and \"runMode\" with values of numbers or nulls" +} -exports['src/validation .isValidClientCertificatesSet returns error message for certs object without url 1'] = ` -Expected \`clientCertificates[0].url\` to be a URL matcher. Instead the value was: \`undefined\` -` +exports['src/validation .isValidClientCertificatesSet returns error message for certs object without url 1'] = { + "key": "clientCertificates[0].url", + "type": "a URL matcher" +} -exports['missing https protocol'] = ` -Expected \`clientCertificates[0].url\` to be an https protocol. Instead the value was: \`"http://url.com"\` -` +exports['missing https protocol'] = { + "key": "clientCertificates[0].url", + "value": "http://url.com", + "type": "an https protocol" +} -exports['invalid url'] = ` -Expected \`clientCertificates[0].url\` to be a valid URL. Instead the value was: \`"not *"\` -` +exports['invalid url'] = { + "key": "clientCertificates[0].url", + "value": "not *", + "type": "a valid URL" +} -exports['not qualified url'] = ` -Expected \`mockConfigKey\` to be a fully qualified URL (starting with \`http://\` or \`https://\`). Instead the value was: \`"url.com"\` -` +exports['not qualified url'] = { + "key": "mockConfigKey", + "value": "url.com", + "type": "a fully qualified URL (starting with `http://` or `https://`)" +} -exports['empty string'] = ` -Expected \`mockConfigKey\` to be a fully qualified URL (starting with \`http://\` or \`https://\`). Instead the value was: \`""\` -` +exports['empty string'] = { + "key": "mockConfigKey", + "value": "", + "type": "a fully qualified URL (starting with `http://` or `https://`)" +} diff --git a/packages/config/lib/index.js b/packages/config/lib/index.js index 3ab8086a695d..3ba750e3a0de 100644 --- a/packages/config/lib/index.js +++ b/packages/config/lib/index.js @@ -26,7 +26,7 @@ const issuedWarnings = new Set() const validateNoBreakingOptions = (breakingCfgOptions, cfg, onWarning, onErr) => { breakingCfgOptions.forEach(({ name, errorKey, newName, isWarning, value }) => { - if (cfg.hasOwnProperty(name)) { + if (_.has(cfg, name)) { if (value && cfg[name] !== value) { // Bail if a value is specified but the config does not have that value. return diff --git a/packages/config/lib/options.ts b/packages/config/lib/options.ts index cd0cfbff9f9b..465c78074cb1 100644 --- a/packages/config/lib/options.ts +++ b/packages/config/lib/options.ts @@ -532,22 +532,22 @@ export const breakingOptions: Array = [ export const breakingRootOptions: Array = [ { name: 'supportFile', - errorKey: 'SUPPORT_FILE_ROOT_NOT_SUPPORTED', + errorKey: 'CONFIG_FILE_INVALID_ROOT_CONFIG', isWarning: false, }, { name: 'specPattern', - errorKey: 'SPEC_PATTERN_ROOT_NOT_SUPPORTED', + errorKey: 'CONFIG_FILE_INVALID_ROOT_CONFIG', isWarning: false, }, { name: 'excludeSpecPattern', - errorKey: 'SPEC_EXCLUDE_PATTERN_ROOT_NOT_SUPPORTED', + errorKey: 'CONFIG_FILE_INVALID_ROOT_CONFIG', isWarning: false, }, { name: 'baseUrl', - errorKey: 'BASE_URL_ROOT_NOT_SUPPORTED', + errorKey: 'CONFIG_FILE_INVALID_ROOT_CONFIG_E2E', isWarning: false, }, ] @@ -557,7 +557,7 @@ export const testingTypeBreakingOptions: { e2e: Array, component component: [ { name: 'baseUrl', - errorKey: 'BASE_URL_CT_NOT_SUPPORTED', + errorKey: 'CONFIG_FILE_INVALID_TESTING_TYPE_CONFIG_COMPONENT', isWarning: false, }, ], diff --git a/packages/config/lib/validation.d.ts b/packages/config/lib/validation.d.ts index b81b541d6d64..1d4ebe15477f 100644 --- a/packages/config/lib/validation.d.ts +++ b/packages/config/lib/validation.d.ts @@ -1,29 +1,36 @@ +// TODO: Remove this file when we land type-safe @packages/config +type ErrResult = { + key: string + value: any + type: string +} + export default { - isValidClientCertificatesSet(_key: string, certsForUrls: any[]): string | true {}, + isValidClientCertificatesSet(_key: string, certsForUrls: any[]): ErrResult | true {}, - isValidBrowser(browser: any): string | true {}, + isValidBrowser(browser: any): ErrResult | true {}, - isValidBrowserList(key: string, browsers: any[]): string | true {}, + isValidBrowserList(key: string, browsers: any[]): ErrResult | true {}, - isValidRetriesConfig(key: string, value: any): string | true {}, + isValidRetriesConfig(key: string, value: any): ErrResult | true {}, - isPlainObject(key: string, value: any): string | true {}, + isPlainObject(key: string, value: any): ErrResult | true {}, - isNumber(key: string, value: any): string | true {}, + isNumber(key: string, value: any): ErrResult | true {}, - isNumberOrFalse(key: string, value: any): string | true {}, + isNumberOrFalse(key: string, value: any): ErrResult | true {}, - isFullyQualifiedUrl(key: string, value: string): string | true {}, + isFullyQualifiedUrl(key: string, value: string): ErrResult | true {}, - isBoolean(key: string, value: any): string | true {}, + isBoolean(key: string, value: any): ErrResult | true {}, - isString(key: string, value: any): string | true {}, + isString(key: string, value: any): ErrResult | true {}, - isArray(key: string, value: any): string | true {}, + isArray(key: string, value: any): ErrResult | true {}, - isStringOrFalse(key: string, value: any): string | true {}, + isStringOrFalse(key: string, value: any): ErrResult | true {}, - isStringOrArrayOfStrings(key: string, value: any): string | true {}, + isStringOrArrayOfStrings(key: string, value: any): ErrResult | true {}, isOneOf(...any: any[]): (key: any, value: any) => boolean {}, } \ No newline at end of file diff --git a/packages/config/lib/validation.js b/packages/config/lib/validation.js index 37fb3f7f878d..75c3ca6ed301 100644 --- a/packages/config/lib/validation.js +++ b/packages/config/lib/validation.js @@ -11,17 +11,12 @@ const path = require('path') const str = JSON.stringify const { isArray, isString, isFinite: isNumber } = _ -/** - * Forms good Markdown-like string message. - * @param {string} key - The key that caused the error - * @param {string} type - The expected type name - * @param {any} value - The actual value - * @returns {string} Formatted error message -*/ const errMsg = (key, value, type) => { - return `Expected \`${key}\` to be ${type}. Instead the value was: \`${str( + return { + key, value, - )}\`` + type, + } } const isFullyQualifiedUrl = (value) => { @@ -91,10 +86,12 @@ const isValidBrowserList = (key, browsers) => { } for (let k = 0; k < browsers.length; k += 1) { - const err = isValidBrowser(browsers[k]) + const validationResult = isValidBrowser(browsers[k]) + + if (validationResult !== true) { + validationResult.list = 'browsers' - if (err !== true) { - return `Found an error while validating the \`browsers\` list. ${err}` + return validationResult } } diff --git a/packages/config/test/unit/index_spec.js b/packages/config/test/unit/index_spec.js index e15cad4afe84..526062fcf480 100644 --- a/packages/config/test/unit/index_spec.js +++ b/packages/config/test/unit/index_spec.js @@ -101,7 +101,8 @@ describe('src/index', () => { 'baseUrl': ' ', }, errorFn) - expect(errorFn).to.have.been.calledWithMatch(/Expected `baseUrl`/) + expect(errorFn).to.have.been.calledWithMatch({ key: 'baseUrl' }) + expect(errorFn).to.have.been.calledWithMatch({ type: 'a fully qualified URL (starting with `http://` or `https://`)' }) }) }) diff --git a/packages/data-context/package.json b/packages/data-context/package.json index a87ba4007720..b7f734949024 100644 --- a/packages/data-context/package.json +++ b/packages/data-context/package.json @@ -47,6 +47,7 @@ }, "devDependencies": { "@packages/config": "0.0.0-development", + "@packages/errors": "0.0.0-development", "@packages/example": "0.0.0-development", "@packages/network": "0.0.0-development", "@packages/resolve-dist": "0.0.0-development", diff --git a/packages/data-context/src/DataContext.ts b/packages/data-context/src/DataContext.ts index 6b072dca0758..071281f1ca59 100644 --- a/packages/data-context/src/DataContext.ts +++ b/packages/data-context/src/DataContext.ts @@ -39,6 +39,7 @@ import { VersionsDataSource } from './sources/VersionsDataSource' import type { Socket, SocketIOServer } from '@packages/socket' import { globalPubSub } from '.' import { InjectedConfigApi, ProjectLifecycleManager } from './data/ProjectLifecycleManager' +import type { CypressError } from '@packages/errors' const IS_DEV_ENV = process.env.CYPRESS_INTERNAL_ENV !== 'production' @@ -50,12 +51,6 @@ export interface InternalDataContextOptions { loadCachedProjects: boolean } -export interface ErrorApiShape { - error: (type: string, ...args: any) => Error & { type: string, details: string, code?: string, isCypressErr: boolean} - message: (type: string, ...args: any) => string - warning: (type: string, ...args: any) => null -} - export interface DataContextConfig { schema: GraphQLSchema mode: 'run' | 'open' @@ -68,7 +63,6 @@ export interface DataContextConfig { appApi: AppApiShape localSettingsApi: LocalSettingsApiShape authApi: AuthApiShape - errorApi: ErrorApiShape configApi: InjectedConfigApi projectApi: ProjectApiShape electronApi: ElectronApiShape @@ -315,7 +309,6 @@ export class DataContext { browserApi: this._config.browserApi, configApi: this._config.configApi, projectApi: this._config.projectApi, - errorApi: this._config.errorApi, electronApi: this._config.electronApi, localSettingsApi: this._config.localSettingsApi, } @@ -366,14 +359,14 @@ export class DataContext { } } - onWarning = (err: { message: string, type?: string, details?: string }) => { + onWarning = (err: CypressError) => { if (this.isRunMode) { // eslint-disable-next-line console.log(chalk.yellow(err.message)) } else { this.coreData.warnings.push({ title: `Warning: ${s.titleize(s.humanize(err.type ?? ''))}`, - message: err.message, + message: err.messageMarkdown || err.message, details: err.details, }) @@ -455,14 +448,6 @@ export class DataContext { } } - error (type: string, ...args: any[]) { - return this._apis.errorApi.error(type, ...args) - } - - warning (type: string, ...args: any[]) { - return this._apis.errorApi.error(type, ...args) - } - private async initializeOpenMode () { if (IS_DEV_ENV && !process.env.CYPRESS_INTERNAL_E2E_TESTING_SELF) { this.actions.dev.watchForRelaunch() diff --git a/packages/data-context/src/data/ProjectConfigIpc.ts b/packages/data-context/src/data/ProjectConfigIpc.ts index 0b806c3a7fa9..d24b06541b95 100644 --- a/packages/data-context/src/data/ProjectConfigIpc.ts +++ b/packages/data-context/src/data/ProjectConfigIpc.ts @@ -1,4 +1,5 @@ /* eslint-disable no-dupe-class-members */ +import type { CypressError, SerializedError } from '@packages/errors' import type { TestingType } from '@packages/types' import type { ChildProcess } from 'child_process' import EventEmitter from 'events' @@ -22,12 +23,6 @@ export interface SerializedLoadConfigReply { requires: string[] } -export interface WarningError { - name: 'Error' - message: string - stack: string -} - /** * The ProjectConfigIpc is an EventEmitter wrapping the childProcess, * adding a "send" method for sending events from the parent process into the childProcess, @@ -64,10 +59,9 @@ export class ProjectConfigIpc extends EventEmitter { return this.childProcess.send({ event, args }) } - on(evt: 'childProcess:unhandledError', listener: (err: WarningError) => void): this + on(evt: 'childProcess:unhandledError', listener: (err: CypressError) => void): this - on(evt: 'setupTestingType:uncaughtError', listener: (err: Error) => void): this - on(evt: 'warning', listener: (warningErr: WarningError) => void): this + on(evt: 'warning', listener: (warningErr: CypressError) => void): this on (evt: string, listener: (...args: any[]) => void) { return super.on(evt, listener) } @@ -79,13 +73,13 @@ export class ProjectConfigIpc extends EventEmitter { * sourcing the config (script error, etc.) */ once(evt: 'loadConfig:reply', listener: (payload: SerializedLoadConfigReply) => void): this - once(evt: 'loadConfig:error', listener: (realErrorCode: string, requiredFile: string, message: string) => void): this + once(evt: 'loadConfig:error', listener: (err: SerializedError) => void): this /** * When */ once(evt: 'setupTestingType:reply', listener: (payload: SetupNodeEventsReply) => void): this - once(evt: 'setupTestingType:error', listener: (error: string, requiredFile: string, stack: string) => void): this + once(evt: 'setupTestingType:error', listener: (error: SerializedError) => void): this once (evt: string, listener: (...args: any[]) => void) { return super.once(evt, listener) } diff --git a/packages/data-context/src/data/ProjectLifecycleManager.ts b/packages/data-context/src/data/ProjectLifecycleManager.ts index 97b62610db34..d853b418f7a1 100644 --- a/packages/data-context/src/data/ProjectLifecycleManager.ts +++ b/packages/data-context/src/data/ProjectLifecycleManager.ts @@ -16,11 +16,12 @@ import debugLib from 'debug' import pDefer from 'p-defer' import fs from 'fs' +import { getError, CypressError, ConfigValidationError } from '@packages/errors' import type { DataContext } from '..' import { LoadConfigReply, SetupNodeEventsReply, ProjectConfigIpc, IpcHandler } from './ProjectConfigIpc' import assert from 'assert' -import type { AllModeOptions, FoundBrowser, FullConfig, TestingType } from '@packages/types' -import type { BaseErrorDataShape, WarningError } from '.' +import type { AllModeOptions, BreakingErrResult, BreakingOption, FoundBrowser, FullConfig, TestingType } from '@packages/types' +import type { BaseErrorDataShape } from '.' import { autoBindDebug } from '../util/autoBindDebug' const debug = debugLib(`cypress:lifecycle:ProjectLifecycleManager`) @@ -38,6 +39,8 @@ export interface SetupFullConfigOptions { options: Partial } +type BreakingValidationFn = (type: BreakingOption, val: BreakingErrResult) => T + /** * All of the APIs injected from @packages/server & @packages/config * since these are not strictly typed @@ -45,17 +48,17 @@ export interface SetupFullConfigOptions { export interface InjectedConfigApi { cypressVersion: string getServerPluginHandlers: () => IpcHandler[] - validateConfig(config: Partial, onErr: (errMsg: string) => never): T + validateConfig(config: Partial, onErr: (errMsg: ConfigValidationError | string) => never): T allowedConfig(config: Cypress.ConfigOptions): Cypress.ConfigOptions updateWithPluginValues(config: FullConfig, modifiedConfig: Partial): FullConfig setupFullConfigWithDefaults(config: SetupFullConfigOptions): Promise - validateRootConfigBreakingChanges(config: Partial, onWarning: (warningMsg: string) => void, onErr: (errMsg: string) => never): T - validateTestingTypeConfigBreakingChanges(config: Partial, testingType: Cypress.TestingType, onWarning: (warningMsg: string) => void, onErr: (errMsg: string) => never): T + validateRootConfigBreakingChanges(config: Partial, onWarning: BreakingValidationFn, onErr: BreakingValidationFn): T + validateTestingTypeConfigBreakingChanges(config: Partial, testingType: Cypress.TestingType, onWarning: BreakingValidationFn, onErr: BreakingValidationFn): T } type State = V extends undefined ? {state: S, value?: V } : {state: S, value: V} -type LoadingStateFor = State<'pending'> | State<'loading', Promise> | State<'loaded', V> | State<'errored', Error> +type LoadingStateFor = State<'pending'> | State<'loading', Promise> | State<'loaded', V> | State<'errored', CypressError> type ConfigResultState = LoadingStateFor @@ -185,7 +188,7 @@ export class ProjectLifecycleManager { if (this._configResult.state === 'errored') { return { title: 'Error Loading Config', - message: this._configResult.value?.message || '', + message: this._configResult.value?.messageMarkdown || '', stack: this._configResult.value?.stack, } } @@ -197,7 +200,7 @@ export class ProjectLifecycleManager { if (this._eventsIpcResult.state === 'errored') { return { title: 'Error Loading Config', - message: this._eventsIpcResult.value?.message || '', + message: this._eventsIpcResult.value?.messageMarkdown || '', stack: this._eventsIpcResult.value?.stack, } } @@ -479,7 +482,7 @@ export class ProjectLifecycleManager { return { ...browser, - warning: browser.warning || this.ctx._apis.errorApi.message('CHROME_WEB_SECURITY_NOT_SUPPORTED', browser.name), + warning: browser.warning || getError('CHROME_WEB_SECURITY_NOT_SUPPORTED', browser.name).message, } }) @@ -571,11 +574,11 @@ export class ProjectLifecycleManager { return this.ctx._apis.configApi.validateTestingTypeConfigBreakingChanges( config, this._currentTestingType, - (warning, ...args) => { - return this.ctx.warning(warning, ...args) + (type, ...args) => { + return getError(type, ...args) }, - (err, ...args) => { - throw this.ctx.error(err, ...args) + (type, ...args) => { + throw getError(type, ...args) }, ) } @@ -583,26 +586,22 @@ export class ProjectLifecycleManager { private validateConfigRoot (config: Cypress.ConfigOptions) { return this.ctx._apis.configApi.validateRootConfigBreakingChanges( config, - (warning, ...args) => { - return this.ctx.warning(warning, ...args) + (type, obj) => { + return getError(type, obj) }, - (err, ...args) => { - throw this.ctx.error(err, ...args) + (type, obj) => { + throw getError(type, obj) }, ) } private validateConfigFile (file: string | false, config: Cypress.ConfigOptions) { this.ctx._apis.configApi.validateConfig(config, (errMsg) => { - if (!file) { - // This should never happen, b/c if the config file is false, the config - // should be the default one - throw this.ctx.error('CONFIG_VALIDATION_ERROR', errMsg) + if (_.isString(errMsg)) { + throw getError('CONFIG_VALIDATION_MSG_ERROR', 'configFile', file || null, errMsg) } - const base = path.basename(file) - - throw this.ctx.error('SETTINGS_VALIDATION_ERROR', base, errMsg) + throw getError('CONFIG_VALIDATION_ERROR', 'configFile', file || null, errMsg) }) } @@ -743,7 +742,7 @@ export class ProjectLifecycleManager { throw err } - throw this.ctx.error('ERROR_READING_FILE', this.envFilePath, err) + throw getError('ERROR_READING_FILE', this.envFilePath, err) } } @@ -1025,29 +1024,13 @@ export class ProjectLifecycleManager { return this.handleChildProcessError(err, ipc, dfd) }) - ipc.on('setupTestingType:uncaughtError', (err) => { - return this.handleChildProcessError(err, ipc, dfd) - }) - ipc.once('loadConfig:reply', (val) => { debug('loadConfig:reply') dfd.resolve({ ...val, initialConfig: JSON.parse(val.initialConfig) }) }) - ipc.once('loadConfig:error', (type, ...args) => { - debug('loadConfig:error %s, rejecting', type) + ipc.once('loadConfig:error', (err) => { this.killChildProcess(child) - - const err = this.ctx.error(type, ...args) - - // if it's a non-cypress error, restore the initial error - if (!(err.message?.length)) { - err.isCypressErr = false - err.message = args[1] - err.code = type - err.name = type - } - dfd.reject(err) }) @@ -1062,8 +1045,8 @@ export class ProjectLifecycleManager { this._cleanupIpc(ipc) - err = this.ctx._apis.errorApi.error('CHILD_PROCESS_UNEXPECTED_ERROR', this._currentTestingType, this.configFile, err.annotated || err.stack || err.message) - err.title = 'Error running plugin' + err = getError('CONFIG_FILE_UNEXPECTED_ERROR', this.configFile || '(unknown config file)', err) + err.title = 'Config process error' // this can sometimes trigger before the promise is fulfilled and // sometimes after, so we need to handle each case differently @@ -1081,7 +1064,7 @@ export class ProjectLifecycleManager { basedir: this.projectRoot, })) - this.ctx.onWarning(this.ctx.error('INCOMPATIBLE_PLUGIN_RETRIES', path.relative(this.projectRoot, retriesPluginPath))) + this.ctx.onWarning(getError('INCOMPATIBLE_PLUGIN_RETRIES', path.relative(this.projectRoot, retriesPluginPath))) } catch (e) { // noop, incompatible plugin not installed } @@ -1181,7 +1164,7 @@ export class ProjectLifecycleManager { throw new Error('NOT DIRECTORY') } } catch (err) { - throw this.ctx.error('NO_PROJECT_FOUND_AT_PROJECT_ROOT', this.projectRoot) + throw getError('NO_PROJECT_FOUND_AT_PROJECT_ROOT', this.projectRoot) } } @@ -1264,7 +1247,7 @@ export class ProjectLifecycleManager { this.ctx.coreData.chosenBrowser = browser ?? null } catch (e) { - const error = e as Error + const error = e as CypressError this.ctx.onWarning(error) } @@ -1277,11 +1260,11 @@ export class ProjectLifecycleManager { // For every registration event, we want to turn into an RPC with the child process ipc.once('setupTestingType:reply', dfd.resolve) - ipc.once('setupTestingType:error', (type, ...args) => { - dfd.reject(this.ctx.error(type, ...args)) + ipc.once('setupTestingType:error', (err) => { + dfd.reject(err) }) - const handleWarning = (warningErr: WarningError) => { + const handleWarning = (warningErr: CypressError) => { debug('plugins process warning:', warningErr.stack) return this.ctx.onWarning(warningErr) @@ -1322,13 +1305,13 @@ export class ProjectLifecycleManager { this._pendingInitialize = pDefer() if (!this._currentTestingType) { + // e2e is assumed to be the default testing type if + // none is passed in run mode this.setCurrentTestingType('e2e') - // TODO: Warn on this - // this.ctx.onWarning(this.ctx.error('TESTING_TYPE_NEEDED_FOR_RUN')) } if (!this.metaState.hasValidConfigFile) { - return this.ctx.onError(this.ctx.error('NO_DEFAULT_CONFIG_FILE_FOUND', this.projectRoot)) + return this.ctx.onError(getError('NO_DEFAULT_CONFIG_FILE_FOUND', this.projectRoot)) } return this._pendingInitialize.promise.finally(() => { @@ -1339,19 +1322,19 @@ export class ProjectLifecycleManager { private configFileWarningCheck () { // Only if they've explicitly specified a config file path do we error, otherwise they'll go through onboarding if (!this.metaState.hasValidConfigFile && this.metaState.hasSpecifiedConfigViaCLI !== false && this.ctx.isRunMode) { - this.ctx.onError(this.ctx.error('CONFIG_FILE_NOT_FOUND', path.basename(this.metaState.hasSpecifiedConfigViaCLI), path.dirname(this.metaState.hasSpecifiedConfigViaCLI))) + this.ctx.onError(getError('CONFIG_FILE_NOT_FOUND', path.basename(this.metaState.hasSpecifiedConfigViaCLI), path.dirname(this.metaState.hasSpecifiedConfigViaCLI))) } if (this.metaState.hasLegacyCypressJson && !this.metaState.hasValidConfigFile && this.ctx.isRunMode) { - this.ctx.onError(this.ctx.error('CONFIG_FILE_MIGRATION_NEEDED', this.projectRoot)) + this.ctx.onError(getError('CONFIG_FILE_MIGRATION_NEEDED', this.projectRoot)) } if (this.metaState.hasMultipleConfigPaths) { - this.ctx.onError(this.ctx.error('CONFIG_FILES_LANGUAGE_CONFLICT', this.projectRoot)) + this.ctx.onError(getError('CONFIG_FILES_LANGUAGE_CONFLICT', this.projectRoot, 'cypress.config.js', 'cypress.config.ts')) } if (this.metaState.hasValidConfigFile && this.metaState.hasLegacyCypressJson) { - this.ctx.onError(this.ctx.error('LEGACY_CONFIG_FILE', this.projectRoot, path.basename(this.configFilePath))) + this.ctx.onError(getError('LEGACY_CONFIG_FILE', path.basename(this.configFilePath), this.projectRoot)) } } diff --git a/packages/data-context/test/unit/config-file-updater.spec.ts b/packages/data-context/test/unit/config-file-updater.spec.ts index 55ba7b2c0628..e8d64748c576 100644 --- a/packages/data-context/test/unit/config-file-updater.spec.ts +++ b/packages/data-context/test/unit/config-file-updater.spec.ts @@ -1,5 +1,5 @@ -import { stripIndent } from '@packages/server/lib/util/strip_indent' import { expect } from 'chai' +import { stripIndent } from 'common-tags' import { insertValueInJSString } from '../../src/util/config-file-updater' const errors = { diff --git a/packages/data-context/test/unit/sources/ProjectDataSource.spec.ts b/packages/data-context/test/unit/sources/ProjectDataSource.spec.ts index 83392bceb77b..a48e091d05af 100644 --- a/packages/data-context/test/unit/sources/ProjectDataSource.spec.ts +++ b/packages/data-context/test/unit/sources/ProjectDataSource.spec.ts @@ -4,7 +4,6 @@ import path from 'path' import { DataContext } from '../../../src' import { graphqlSchema } from '@packages/graphql/src/schema' import { AppApiShape, AuthApiShape, ElectronApiShape, LocalSettingsApiShape, ProjectApiShape } from '../../../src/actions' -import { ErrorApiShape } from '../../../src/DataContext' import { InjectedConfigApi } from '../../../src/data' describe('matchedSpecs', () => { @@ -145,7 +144,6 @@ describe('findSpecs', () => { appApi: {} as AppApiShape, localSettingsApi: {} as LocalSettingsApiShape, authApi: {} as AuthApiShape, - errorApi: {} as ErrorApiShape, configApi: { getServerPluginHandlers: () => [], } as InjectedConfigApi, diff --git a/packages/driver/cypress/e2e/commands/clock.cy.js b/packages/driver/cypress/e2e/commands/clock.cy.js index 01ade377b6b6..60838517063c 100644 --- a/packages/driver/cypress/e2e/commands/clock.cy.js +++ b/packages/driver/cypress/e2e/commands/clock.cy.js @@ -114,7 +114,7 @@ describe('src/cy/commands/clock', () => { }) // this test was written to catch a bug in lolex (dep, now @sinonjs/fake-timers) 3 and was fixed by lolex 4 upgrade, - it('doesn\'t override window.performance members', () => { + it(`doesn't override window.performance members`, () => { cy.clock() .then((clock) => { cy.window().then((win) => { diff --git a/packages/driver/cypress/e2e/commands/navigation.cy.js b/packages/driver/cypress/e2e/commands/navigation.cy.js index 30d9b9179651..311eea7f6a64 100644 --- a/packages/driver/cypress/e2e/commands/navigation.cy.js +++ b/packages/driver/cypress/e2e/commands/navigation.cy.js @@ -814,7 +814,7 @@ describe('src/cy/commands/navigation', () => { }) // https://github.com/cypress-io/cypress/issues/1311 - it('window immediately resolves and doesn\'t reload when visiting the same URL with hashes', () => { + it(`window immediately resolves and doesn't reload when visiting the same URL with hashes`, () => { const onLoad = cy.stub() cy diff --git a/packages/driver/cypress/e2e/commands/net_stubbing.cy.ts b/packages/driver/cypress/e2e/commands/net_stubbing.cy.ts index e3118a69ba02..60be8269fae6 100644 --- a/packages/driver/cypress/e2e/commands/net_stubbing.cy.ts +++ b/packages/driver/cypress/e2e/commands/net_stubbing.cy.ts @@ -1,4 +1,5 @@ import { getDisplayUrlMatcher } from '@packages/driver/src/cy/net-stubbing/route-matcher-log' + import type { RouteMatcherOptions } from '@packages/net-stubbing/lib/external-types' const testFail = (cb, expectedDocsUrl = 'https://on.cypress.io/intercept') => { @@ -2016,7 +2017,7 @@ describe('network stubbing', function () { }) }) - it('doesn\'t automatically parse JSON request bodies if content-type is wrong', function () { + it(`doesn't automatically parse JSON request bodies if content-type is wrong`, function () { const p = Promise.defer() cy.intercept('/post-only', (req) => { @@ -2786,7 +2787,7 @@ describe('network stubbing', function () { }) }) - it('doesn\'t automatically parse JSON response bodies if content-type is wrong', function () { + it(`doesn't automatically parse JSON response bodies if content-type is wrong`, function () { const p = Promise.defer() cy.intercept('/fixtures/json.txt*', (req) => { @@ -2806,7 +2807,7 @@ describe('network stubbing', function () { }) // @see https://github.com/cypress-io/cypress/issues/16722 - it('doesn\'t automatically parse response bodies if content is binary', function () { + it(`doesn't automatically parse response bodies if content is binary`, function () { const expectedBody = [120, 42, 7] const assertBody = (body: ArrayBuffer) => { const uint8 = new Uint8Array(body) @@ -3120,7 +3121,7 @@ describe('network stubbing', function () { }) }) - it('doesn\'t fail test if network error occurs retrieving response and response is not intercepted', { + it(`doesn't fail test if network error occurs retrieving response and response is not intercepted`, { // TODO: for some reason, this test is busted in FF browser: '!firefox', }, function () { diff --git a/packages/driver/src/cy/chai/inspect.ts b/packages/driver/src/cy/chai/inspect.ts index 512336709ff4..5dfccd83fdc0 100644 --- a/packages/driver/src/cy/chai/inspect.ts +++ b/packages/driver/src/cy/chai/inspect.ts @@ -54,6 +54,18 @@ export function create (chai) { typeof object.nodeName === 'string' } + // We can't just check if object instanceof ShadowRoot, because it might be the document of an iframe, + // which in Chrome 99+ is a separate class, and instanceof ShadowRoot returns false. + const isShadowRoot = function (object) { + return isDOMElement(object.host) && object.host.shadowRoot === object + } + + // We can't just check if object instanceof Document, because it might be the document of an iframe, + // which in Chrome 99+ is a separate class, and instanceof Document returns false. + const isDocument = function (object) { + return object.defaultView && object.defaultView === object.defaultView.window + } + let formatValueHook const setFormatValueHook = (fn) => formatValueHook = fn @@ -124,6 +136,14 @@ export function create (chai) { } } + if (isShadowRoot(value)) { + return value.innerHTML + } + + if (isDocument(value)) { + return value.documentElement.outerHTML + } + // Look up the keys of the object. let visibleKeys = getEnumerableProperties(value) let keys = ctx.showHidden ? getProperties(value) : visibleKeys diff --git a/packages/driver/src/cy/commands/navigation.ts b/packages/driver/src/cy/commands/navigation.ts index 78ea12e7b579..c3afb98731c6 100644 --- a/packages/driver/src/cy/commands/navigation.ts +++ b/packages/driver/src/cy/commands/navigation.ts @@ -8,7 +8,6 @@ import $errUtils from '../../cypress/error_utils' import $Log from '../../cypress/log' import { bothUrlsMatchAndOneHasHash } from '../navigation' import { $Location } from '../../cypress/location' -import type { RunState } from '../../cypress/runner' import debugFn from 'debug' const debug = debugFn('cypress:driver:navigation') @@ -1013,7 +1012,7 @@ export default (Commands, Cypress, cy, state, config) => { // tell our backend we're changing domains // TODO: add in other things we want to preserve // state for like scrollTop - let s: RunState = { + let s: Record = { currentId: id, tests: Cypress.runner.getTestsState(), startTime: Cypress.runner.getStartTime(), diff --git a/packages/driver/src/cypress.ts b/packages/driver/src/cypress.ts index c855d23665e4..b00fc15b3e0f 100644 --- a/packages/driver/src/cypress.ts +++ b/packages/driver/src/cypress.ts @@ -146,23 +146,30 @@ class $Cypress { this.config = $SetterGetter.create(config, (config) => { if (!window.top.__cySkipValidateConfig) { validateNoReadOnlyConfig(config, (errProperty) => { - let errMessage - - if (this.state('runnable')) { - errMessage = $errUtils.errByPath('config.invalid_cypress_config_override', { - errProperty, - }) - } else { - errMessage = $errUtils.errByPath('config.invalid_test_config_override', { - errProperty, - }) - } - - throw new this.state('specWindow').Error(errMessage) + const errPath = this.state('runnable') + ? 'config.invalid_cypress_config_override' + : 'config.invalid_test_config_override' + + const errMsg = $errUtils.errByPath(errPath, { + errProperty, + }) + + throw new this.state('specWindow').Error(errMsg) }) } - validate(config, (errMsg) => { + validate(config, (errResult) => { + const stringify = (str) => format(JSON.stringify(str)) + + const format = (str) => `\`${str}\`` + + // TODO: this does not use the @packages/error rewriting rules + // for stdout vs markdown - it always inserts backticks for markdown + // and those leak out into the stdout formatting. + const errMsg = _.isString(errResult) + ? errResult + : `Expected ${format(errResult.key)} to be ${errResult.type}.\n\nInstead the value was: ${stringify(errResult.value)}\`` + throw new this.state('specWindow').Error(errMsg) }) }) diff --git a/packages/driver/src/cypress/commands.ts b/packages/driver/src/cypress/commands.ts index e90682f08a7e..517f3cd08498 100644 --- a/packages/driver/src/cypress/commands.ts +++ b/packages/driver/src/cypress/commands.ts @@ -1,10 +1,8 @@ import _ from 'lodash' - -import $errUtils from './error_utils' -import $stackUtils from './stack_utils' - import { allCommands } from '../cy/commands' import { addCommand } from '../cy/net-stubbing' +import $errUtils from './error_utils' +import $stackUtils from './stack_utils' const PLACEHOLDER_COMMANDS = ['mount', 'hover'] @@ -212,7 +210,7 @@ export default { errProps: { appendToStack: { title: 'From Cypress Internals', - content: $stackUtils.stackWithoutMessage((new Error('add command internal stack')).stack), + content: $stackUtils.stackWithoutMessage((new Error('add command internal stack')).stack || ''), } }, }) } diff --git a/packages/driver/src/cypress/error_utils.ts b/packages/driver/src/cypress/error_utils.ts index 7d7cf105efd2..9c58d6950aa8 100644 --- a/packages/driver/src/cypress/error_utils.ts +++ b/packages/driver/src/cypress/error_utils.ts @@ -1,12 +1,11 @@ // See: ./errorScenarios.md for details about error messages and stack traces -import _ from 'lodash' import chai from 'chai' - +import _ from 'lodash' import $dom from '../dom' -import $utils from './utils' -import $stackUtils, { StackAndCodeFrameIndex } from './stack_utils' import $errorMessages from './error_messages' +import $stackUtils, { StackAndCodeFrameIndex } from './stack_utils' +import $utils from './utils' const ERROR_PROPS = 'message type name stack sourceMappedStack parsedStack fileName lineNumber columnNumber host uncaught actual expected showDiff isPending docsUrl codeFrame'.split(' ') const ERR_PREPARED_FOR_SERIALIZATION = Symbol('ERR_PREPARED_FOR_SERIALIZATION') @@ -405,7 +404,7 @@ const stackAndCodeFrameIndex = (err, userInvocationStack): StackAndCodeFrameInde return $stackUtils.stackWithUserInvocationStackSpliced(err, userInvocationStack) } - return { stack: $stackUtils.replacedStack(err, userInvocationStack) } + return { stack: $stackUtils.replacedStack(err, userInvocationStack) || '' } } const preferredStackAndCodeFrameIndex = (err, userInvocationStack) => { diff --git a/packages/driver/src/cypress/stack_utils.ts b/packages/driver/src/cypress/stack_utils.ts index a3f3c12ee6ef..ddcfb04b9109 100644 --- a/packages/driver/src/cypress/stack_utils.ts +++ b/packages/driver/src/cypress/stack_utils.ts @@ -7,7 +7,9 @@ import { codeFrameColumns } from '@babel/code-frame' import $utils from './utils' import $sourceMapUtils from './source_map_utils' -import { getStackLines, replacedStack, stackWithoutMessage, splitStack, unsplitStack } from '@packages/server/lib/util/stack_utils' + +// Intentionally deep-importing from @packages/errors so as to not bundle the entire @packages/errors in the client unnecessarily +import { getStackLines, replacedStack, stackWithoutMessage, splitStack, unsplitStack } from '@packages/errors/src/stackUtils' const whitespaceRegex = /^(\s*)*/ const stackLineRegex = /^\s*(at )?.*@?\(?.*\:\d+\:\d+\)?$/ @@ -144,13 +146,21 @@ const captureUserInvocationStack = (ErrorConstructor, userInvocationStack?) => { if (!userInvocationStack) { const newErr = new ErrorConstructor('userInvocationStack') + userInvocationStack = newErr.stack + // if browser natively supports Error.captureStackTrace, use it (chrome) (must be bound) // otherwise use our polyfill on top.Error const captureStackTrace = ErrorConstructor.captureStackTrace ? ErrorConstructor.captureStackTrace.bind(ErrorConstructor) : Error.captureStackTrace captureStackTrace(newErr, captureUserInvocationStack) - userInvocationStack = newErr.stack + // On Chrome 99+, captureStackTrace strips away the whole stack, + // leaving nothing beyond the error message. If we get back a single line + // (just the error message with no stack trace), then use the original value + // instead of the trimmed one. + if (newErr.stack.match('\n')) { + userInvocationStack = newErr.stack + } } userInvocationStack = normalizedUserInvocationStack(userInvocationStack) diff --git a/packages/electron/lib/electron.js b/packages/electron/lib/electron.js index d1eb85063085..58d5dbb0d6fc 100644 --- a/packages/electron/lib/electron.js +++ b/packages/electron/lib/electron.js @@ -97,7 +97,7 @@ module.exports = { debug('dest path %s', dest) // make sure this path exists! - return fs.statAsync(appPath) + return fs.accessAsync(appPath) .then(() => { debug('appPath exists %s', appPath) diff --git a/packages/errors/README.md b/packages/errors/README.md new file mode 100644 index 000000000000..237ec22ab331 --- /dev/null +++ b/packages/errors/README.md @@ -0,0 +1,5 @@ +## @packages/errors + +Error definitions and utilities for Cypress + +See [Error Handling Guide](../../guides/error-handling.md) for more info \ No newline at end of file diff --git a/packages/errors/__snapshot-html__/AUTOMATION_SERVER_DISCONNECTED.html b/packages/errors/__snapshot-html__/AUTOMATION_SERVER_DISCONNECTED.html new file mode 100644 index 000000000000..170d59bacaab --- /dev/null +++ b/packages/errors/__snapshot-html__/AUTOMATION_SERVER_DISCONNECTED.html @@ -0,0 +1,38 @@ + + + + + + + + + + + +
The automation client disconnected. Cannot continue running tests.
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/BAD_POLICY_WARNING.html b/packages/errors/__snapshot-html__/BAD_POLICY_WARNING.html new file mode 100644 index 000000000000..617575adb031 --- /dev/null +++ b/packages/errors/__snapshot-html__/BAD_POLICY_WARNING.html @@ -0,0 +1,45 @@ + + + + + + + + + + + +
Cypress detected policy settings on your computer that may cause issues.
+
+The following policies were detected that may prevent Cypress from automating Chrome:
+
+ - HKEY_LOCAL_MACHINE\Software\Policies\Google\Chrome\ProxyServer
+ - HKEY_CURRENT_USER\Software\Policies\Google\Chromium\ExtensionSettings
+
+For more information, see https://on.cypress.io/bad-browser-policy
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/BAD_POLICY_WARNING_TOOLTIP.html b/packages/errors/__snapshot-html__/BAD_POLICY_WARNING_TOOLTIP.html new file mode 100644 index 000000000000..a0c6acb1901f --- /dev/null +++ b/packages/errors/__snapshot-html__/BAD_POLICY_WARNING_TOOLTIP.html @@ -0,0 +1,38 @@ + + + + + + + + + + + +
Cypress detected policy settings on your computer that may cause issues with using this browser. For more information, see https://on.cypress.io/bad-browser-policy
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/BROWSER_NOT_FOUND_BY_NAME - canary.html b/packages/errors/__snapshot-html__/BROWSER_NOT_FOUND_BY_NAME - canary.html new file mode 100644 index 000000000000..95f021d5471a --- /dev/null +++ b/packages/errors/__snapshot-html__/BROWSER_NOT_FOUND_BY_NAME - canary.html @@ -0,0 +1,67 @@ + + + + + + + + + + + +
Can't run because you've entered an invalid browser name.
+
+Browser: canary was not found on your system or is not supported by Cypress.
+
+Cypress supports the following browsers:
+ - electron
+ - chrome
+ - chromium
+ - chrome:canary
+ - edge
+ - firefox
+
+You can also use a custom browser: https://on.cypress.io/customize-browsers
+
+Available browsers found on your system are:
+ - chrome
+ - chromium
+ - chrome:beta
+ - chrome:canary
+ - firefox
+ - firefox:dev
+ - firefox:nightly
+ - edge
+ - edge:canary
+ - edge:beta
+ - edge:dev
+
+Note: In Cypress version 4.0.0, Canary must be launched as chrome:canary, not canary.
+
+See https://on.cypress.io/migration-guide for more information on breaking changes in 4.0.0.
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/BROWSER_NOT_FOUND_BY_NAME.html b/packages/errors/__snapshot-html__/BROWSER_NOT_FOUND_BY_NAME.html new file mode 100644 index 000000000000..d29ace7a0dc5 --- /dev/null +++ b/packages/errors/__snapshot-html__/BROWSER_NOT_FOUND_BY_NAME.html @@ -0,0 +1,63 @@ + + + + + + + + + + + +
Can't run because you've entered an invalid browser name.
+
+Browser: invalid-browser was not found on your system or is not supported by Cypress.
+
+Cypress supports the following browsers:
+ - electron
+ - chrome
+ - chromium
+ - chrome:canary
+ - edge
+ - firefox
+
+You can also use a custom browser: https://on.cypress.io/customize-browsers
+
+Available browsers found on your system are:
+ - chrome
+ - chromium
+ - chrome:beta
+ - chrome:canary
+ - firefox
+ - firefox:dev
+ - firefox:nightly
+ - edge
+ - edge:canary
+ - edge:beta
+ - edge:dev
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/BROWSER_NOT_FOUND_BY_PATH.html b/packages/errors/__snapshot-html__/BROWSER_NOT_FOUND_BY_PATH.html new file mode 100644 index 000000000000..c6c0b962e06c --- /dev/null +++ b/packages/errors/__snapshot-html__/BROWSER_NOT_FOUND_BY_PATH.html @@ -0,0 +1,44 @@ + + + + + + + + + + + +
We could not identify a known browser at the path you provided: /path/does/not/exist
+
+Read more about how to troubleshoot launching browsers: https://on.cypress.io/troubleshooting-launching-browsers
+
+The output from the command we ran was:
+
+fail whale
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/BUNDLE_ERROR.html b/packages/errors/__snapshot-html__/BUNDLE_ERROR.html new file mode 100644 index 000000000000..e64518f7a92c --- /dev/null +++ b/packages/errors/__snapshot-html__/BUNDLE_ERROR.html @@ -0,0 +1,51 @@ + + + + + + + + + + + +
Oops...we found an error preparing this test file:
+
+  > /path/to/file
+
+The error was:
+
+fail whale
+
+This occurred while Cypress was compiling and bundling your test code. This is usually caused by:
+
+- A missing file or dependency
+- A syntax error in the file or one of its dependencies
+
+Fix the error in your code and re-run your tests.
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/CANNOT_CONNECT_BASE_URL.html b/packages/errors/__snapshot-html__/CANNOT_CONNECT_BASE_URL.html new file mode 100644 index 000000000000..2708c07753de --- /dev/null +++ b/packages/errors/__snapshot-html__/CANNOT_CONNECT_BASE_URL.html @@ -0,0 +1,40 @@ + + + + + + + + + + + +
Cypress failed to verify that your server is running.
+
+Please start this server and then run Cypress again.
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/CANNOT_CONNECT_BASE_URL_RETRYING - retrying.html b/packages/errors/__snapshot-html__/CANNOT_CONNECT_BASE_URL_RETRYING - retrying.html new file mode 100644 index 000000000000..d0d57752b810 --- /dev/null +++ b/packages/errors/__snapshot-html__/CANNOT_CONNECT_BASE_URL_RETRYING - retrying.html @@ -0,0 +1,38 @@ + + + + + + + + + + + +
We will try connecting to it 60 more times...
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/CANNOT_CONNECT_BASE_URL_RETRYING.html b/packages/errors/__snapshot-html__/CANNOT_CONNECT_BASE_URL_RETRYING.html new file mode 100644 index 000000000000..ce25c081ad9a --- /dev/null +++ b/packages/errors/__snapshot-html__/CANNOT_CONNECT_BASE_URL_RETRYING.html @@ -0,0 +1,46 @@ + + + + + + + + + + + +
Cypress could not verify that this server is running:
+
+  > http://localhost:3000
+
+We are verifying this server because it has been configured as your baseUrl.
+
+Cypress automatically waits until your server is accessible before running tests.
+
+We will try connecting to it 60 more times...
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/CANNOT_CONNECT_BASE_URL_WARNING.html b/packages/errors/__snapshot-html__/CANNOT_CONNECT_BASE_URL_WARNING.html new file mode 100644 index 000000000000..555dfe4a1431 --- /dev/null +++ b/packages/errors/__snapshot-html__/CANNOT_CONNECT_BASE_URL_WARNING.html @@ -0,0 +1,42 @@ + + + + + + + + + + + +
Cypress could not verify that this server is running:
+
+  > http://localhost:3000
+
+This server has been configured as your baseUrl, and tests will likely fail if it is not running.
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/CANNOT_CREATE_PROJECT_TOKEN.html b/packages/errors/__snapshot-html__/CANNOT_CREATE_PROJECT_TOKEN.html new file mode 100644 index 000000000000..59fd38858196 --- /dev/null +++ b/packages/errors/__snapshot-html__/CANNOT_CREATE_PROJECT_TOKEN.html @@ -0,0 +1,38 @@ + + + + + + + + + + + +
Can't create project's secret key.
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/CANNOT_FETCH_PROJECT_TOKEN.html b/packages/errors/__snapshot-html__/CANNOT_FETCH_PROJECT_TOKEN.html new file mode 100644 index 000000000000..c4df34380cab --- /dev/null +++ b/packages/errors/__snapshot-html__/CANNOT_FETCH_PROJECT_TOKEN.html @@ -0,0 +1,38 @@ + + + + + + + + + + + +
Can't find project's secret key.
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/CANNOT_RECORD_NO_PROJECT_ID.html b/packages/errors/__snapshot-html__/CANNOT_RECORD_NO_PROJECT_ID.html new file mode 100644 index 000000000000..c682601b3f0d --- /dev/null +++ b/packages/errors/__snapshot-html__/CANNOT_RECORD_NO_PROJECT_ID.html @@ -0,0 +1,48 @@ + + + + + + + + + + + +
You passed the --record flag but this project has not been setup to record.
+
+This project is missing the projectId inside of: /path/to/cypress.json
+
+We cannot uniquely identify this project without this id.
+
+You need to setup this project to record. This will generate a unique projectId.
+
+Alternatively if you omit the --record flag this project will run without recording.
+
+https://on.cypress.io/recording-project-runs
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/CANNOT_REMOVE_OLD_BROWSER_PROFILES.html b/packages/errors/__snapshot-html__/CANNOT_REMOVE_OLD_BROWSER_PROFILES.html new file mode 100644 index 000000000000..2763657e162e --- /dev/null +++ b/packages/errors/__snapshot-html__/CANNOT_REMOVE_OLD_BROWSER_PROFILES.html @@ -0,0 +1,44 @@ + + + + + + + + + + + +
Warning: We failed to remove old browser profiles from previous runs.
+
+This error will not alter the exit code.
+
+Error: fail whale
+    at makeErr (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)
+    at CANNOT_REMOVE_OLD_BROWSER_PROFILES (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/CANNOT_TRASH_ASSETS.html b/packages/errors/__snapshot-html__/CANNOT_TRASH_ASSETS.html new file mode 100644 index 000000000000..3ab26c3ef702 --- /dev/null +++ b/packages/errors/__snapshot-html__/CANNOT_TRASH_ASSETS.html @@ -0,0 +1,44 @@ + + + + + + + + + + + +
Warning: We failed to trash the existing run results.
+
+This error will not alter the exit code.
+
+Error: fail whale
+    at makeErr (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)
+    at CANNOT_TRASH_ASSETS (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/CDP_COULD_NOT_CONNECT.html b/packages/errors/__snapshot-html__/CDP_COULD_NOT_CONNECT.html new file mode 100644 index 000000000000..8cf89fe130b0 --- /dev/null +++ b/packages/errors/__snapshot-html__/CDP_COULD_NOT_CONNECT.html @@ -0,0 +1,46 @@ + + + + + + + + + + + +
Cypress failed to make a connection to the Chrome DevTools Protocol after retrying for 50 seconds.
+
+This usually indicates there was a problem opening the Chrome browser.
+
+The CDP port requested was 2345.
+
+Error: fail whale
+    at makeErr (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)
+    at CDP_COULD_NOT_CONNECT (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/CDP_COULD_NOT_RECONNECT.html b/packages/errors/__snapshot-html__/CDP_COULD_NOT_RECONNECT.html new file mode 100644 index 000000000000..d43f466e1880 --- /dev/null +++ b/packages/errors/__snapshot-html__/CDP_COULD_NOT_RECONNECT.html @@ -0,0 +1,42 @@ + + + + + + + + + + + +
There was an error reconnecting to the Chrome DevTools protocol. Please restart the browser.
+
+Error: fail whale
+    at makeErr (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)
+    at CDP_COULD_NOT_RECONNECT (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/CDP_RETRYING_CONNECTION.html b/packages/errors/__snapshot-html__/CDP_RETRYING_CONNECTION.html new file mode 100644 index 000000000000..da6e47b6aaa9 --- /dev/null +++ b/packages/errors/__snapshot-html__/CDP_RETRYING_CONNECTION.html @@ -0,0 +1,38 @@ + + + + + + + + + + + +
Still waiting to connect to Chrome, retrying in 1 second (attempt 1/62)
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/CDP_VERSION_TOO_OLD - older.html b/packages/errors/__snapshot-html__/CDP_VERSION_TOO_OLD - older.html new file mode 100644 index 000000000000..401ca5b3a607 --- /dev/null +++ b/packages/errors/__snapshot-html__/CDP_VERSION_TOO_OLD - older.html @@ -0,0 +1,38 @@ + + + + + + + + + + + +
A minimum CDP version of 1.3 is required, but the current browser has an older version.
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/CDP_VERSION_TOO_OLD.html b/packages/errors/__snapshot-html__/CDP_VERSION_TOO_OLD.html new file mode 100644 index 000000000000..b2f35a65c725 --- /dev/null +++ b/packages/errors/__snapshot-html__/CDP_VERSION_TOO_OLD.html @@ -0,0 +1,38 @@ + + + + + + + + + + + +
A minimum CDP version of 1.3 is required, but the current browser has 1.2.
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/CHROME_WEB_SECURITY_NOT_SUPPORTED.html b/packages/errors/__snapshot-html__/CHROME_WEB_SECURITY_NOT_SUPPORTED.html new file mode 100644 index 000000000000..78a59080d890 --- /dev/null +++ b/packages/errors/__snapshot-html__/CHROME_WEB_SECURITY_NOT_SUPPORTED.html @@ -0,0 +1,40 @@ + + + + + + + + + + + +
Your project has set the configuration option: chromeWebSecurity to false
+
+This option will not have an effect in Firefox. Tests that rely on web security being disabled will not run as expected.
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/CONFIG_FILES_LANGUAGE_CONFLICT.html b/packages/errors/__snapshot-html__/CONFIG_FILES_LANGUAGE_CONFLICT.html new file mode 100644 index 000000000000..1f9adc12d03a --- /dev/null +++ b/packages/errors/__snapshot-html__/CONFIG_FILES_LANGUAGE_CONFLICT.html @@ -0,0 +1,42 @@ + + + + + + + + + + + +
There is both a cypress.config.js and a cypress.config.ts at the location below:
+
+  > /path/to/project/root
+
+Cypress does not know which one to read for config. Please remove one of the two and try again.
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/CONFIG_FILE_DEV_SERVER_IS_NOT_A_FUNCTION.html b/packages/errors/__snapshot-html__/CONFIG_FILE_DEV_SERVER_IS_NOT_A_FUNCTION.html new file mode 100644 index 000000000000..7072a919238a --- /dev/null +++ b/packages/errors/__snapshot-html__/CONFIG_FILE_DEV_SERVER_IS_NOT_A_FUNCTION.html @@ -0,0 +1,54 @@ + + + + + + + + + + + +
Your configFile is invalid: /path/to/config.ts
+
+The component.devServer() must be a function with the following signature:
+
+{
+  component: {
+    devServer (cypressDevServerConfig, devServerConfig) {
+      // start dev server here
+  }
+}
+
+Instead, we saw:
+
+{}
+
+Learn more: https://on.cypress.io/dev-server
+
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/CONFIG_FILE_INVALID_DEV_START_EVENT.html b/packages/errors/__snapshot-html__/CONFIG_FILE_INVALID_DEV_START_EVENT.html new file mode 100644 index 000000000000..cd88c8945491 --- /dev/null +++ b/packages/errors/__snapshot-html__/CONFIG_FILE_INVALID_DEV_START_EVENT.html @@ -0,0 +1,49 @@ + + + + + + + + + + + +
To run component tests, Cypress needs you to configure the dev-server:start event.
+
+Please update this file: /path/to/plugins/file.js
+
+module.exports = (on, config) => {
+  on('dev-server:start', () => {
+    // start dev server here
+    return startDevServer(...)
+  }
+}
+
+https://on.cypress.io/component-testing
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/CONFIG_FILE_INVALID_ROOT_CONFIG.html b/packages/errors/__snapshot-html__/CONFIG_FILE_INVALID_ROOT_CONFIG.html new file mode 100644 index 000000000000..27000687e8c4 --- /dev/null +++ b/packages/errors/__snapshot-html__/CONFIG_FILE_INVALID_ROOT_CONFIG.html @@ -0,0 +1,51 @@ + + + + + + + + + + + +
The specPattern configuration option is now invalid when set from the root of the config object in Cypress version 10.0.0.
+
+It is now configured separately as a testing type property: e2e.specPattern and component.specPattern
+
+{
+  e2e: {
+    specPattern: '...',
+  },
+  component: {
+    specPattern: '...',
+  },
+}
+
+https://on.cypress.io/migration-guide
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/CONFIG_FILE_INVALID_ROOT_CONFIG_E2E.html b/packages/errors/__snapshot-html__/CONFIG_FILE_INVALID_ROOT_CONFIG_E2E.html new file mode 100644 index 000000000000..a1453f31d8a6 --- /dev/null +++ b/packages/errors/__snapshot-html__/CONFIG_FILE_INVALID_ROOT_CONFIG_E2E.html @@ -0,0 +1,48 @@ + + + + + + + + + + + +
The baseUrl configuration option is now invalid when set from the root of the config object in Cypress version 10.0.0.
+
+It is now configured separately as a testing type property: e2e.baseUrl
+
+{
+  e2e: {
+    baseUrl: '...',
+  }
+}
+
+https://on.cypress.io/migration-guide
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/CONFIG_FILE_INVALID_TESTING_TYPE_CONFIG_COMPONENT.html b/packages/errors/__snapshot-html__/CONFIG_FILE_INVALID_TESTING_TYPE_CONFIG_COMPONENT.html new file mode 100644 index 000000000000..bbcb84ee39bf --- /dev/null +++ b/packages/errors/__snapshot-html__/CONFIG_FILE_INVALID_TESTING_TYPE_CONFIG_COMPONENT.html @@ -0,0 +1,48 @@ + + + + + + + + + + + +
The component.baseUrl configuration option is not valid for component testing.
+
+Please remove this option or add this as an e2e testing type property: e2e.baseUrl
+
+{
+  e2e: {
+    baseUrl: '...',
+  }
+}
+
+https://on.cypress.io/migration-guide
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/CONFIG_FILE_MIGRATION_NEEDED.html b/packages/errors/__snapshot-html__/CONFIG_FILE_MIGRATION_NEEDED.html new file mode 100644 index 000000000000..2164b4527228 --- /dev/null +++ b/packages/errors/__snapshot-html__/CONFIG_FILE_MIGRATION_NEEDED.html @@ -0,0 +1,43 @@ + + + + + + + + + + + +
There is a cypress.json file at the path: /path/to/projectRoot
+
+Cypress version 10.0.0 no longer supports cypress.json.
+
+Please run cypress open to launch the migration tool to migrate to cypress.config.{ts|js}.
+
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/CONFIG_FILE_NOT_FOUND.html b/packages/errors/__snapshot-html__/CONFIG_FILE_NOT_FOUND.html new file mode 100644 index 000000000000..f2cf222723ba --- /dev/null +++ b/packages/errors/__snapshot-html__/CONFIG_FILE_NOT_FOUND.html @@ -0,0 +1,40 @@ + + + + + + + + + + + +
Could not find a Cypress configuration file.
+
+We looked but did not find a cypress.json file in this folder: /path/to/project/root
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/CONFIG_FILE_REQUIRE_ERROR.html b/packages/errors/__snapshot-html__/CONFIG_FILE_REQUIRE_ERROR.html new file mode 100644 index 000000000000..b5c70d176741 --- /dev/null +++ b/packages/errors/__snapshot-html__/CONFIG_FILE_REQUIRE_ERROR.html @@ -0,0 +1,44 @@ + + + + + + + + + + + +
Your configFile is invalid: /path/to/cypress.config.js
+
+It threw an error when required, check the stack trace below:
+
+Error: fail whale
+    at makeErr (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)
+    at CONFIG_FILE_REQUIRE_ERROR (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/CONFIG_FILE_SETUP_NODE_EVENTS_ERROR - component.html b/packages/errors/__snapshot-html__/CONFIG_FILE_SETUP_NODE_EVENTS_ERROR - component.html new file mode 100644 index 000000000000..bd9ea07ad5e8 --- /dev/null +++ b/packages/errors/__snapshot-html__/CONFIG_FILE_SETUP_NODE_EVENTS_ERROR - component.html @@ -0,0 +1,44 @@ + + + + + + + + + + + +
Your configFile threw an error from: /path/to/cypress.config.js
+
+The error was thrown while executing your component.setupNodeEvents() function:
+
+Error: fail whale
+    at makeErr (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)
+    at CONFIG_FILE_SETUP_NODE_EVENTS_ERROR (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/CONFIG_FILE_SETUP_NODE_EVENTS_ERROR.html b/packages/errors/__snapshot-html__/CONFIG_FILE_SETUP_NODE_EVENTS_ERROR.html new file mode 100644 index 000000000000..216fefd7db97 --- /dev/null +++ b/packages/errors/__snapshot-html__/CONFIG_FILE_SETUP_NODE_EVENTS_ERROR.html @@ -0,0 +1,44 @@ + + + + + + + + + + + +
Your configFile threw an error from: /path/to/cypress.config.js
+
+The error was thrown while executing your e2e.setupNodeEvents() function:
+
+Error: fail whale
+    at makeErr (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)
+    at CONFIG_FILE_SETUP_NODE_EVENTS_ERROR (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/CONFIG_FILE_UNEXPECTED_ERROR.html b/packages/errors/__snapshot-html__/CONFIG_FILE_UNEXPECTED_ERROR.html new file mode 100644 index 000000000000..3b8eb008256f --- /dev/null +++ b/packages/errors/__snapshot-html__/CONFIG_FILE_UNEXPECTED_ERROR.html @@ -0,0 +1,44 @@ + + + + + + + + + + + +
Your configFile threw an error from: /path/to/cypress.config.js
+
+We stopped running your tests because your config file crashed.
+
+Error: fail whale
+    at makeErr (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)
+    at CONFIG_FILE_UNEXPECTED_ERROR (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/CONFIG_VALIDATION_ERROR - invalidArray.html b/packages/errors/__snapshot-html__/CONFIG_VALIDATION_ERROR - invalidArray.html new file mode 100644 index 000000000000..d9c965fe506b --- /dev/null +++ b/packages/errors/__snapshot-html__/CONFIG_VALIDATION_ERROR - invalidArray.html @@ -0,0 +1,48 @@ + + + + + + + + + + + +
Your configFile at cypress.json set an invalid value:
+
+Expected defaultCommandTimeout to be a number.
+
+Instead the value was: 
+
+[
+  1,
+  2,
+  3
+]
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/CONFIG_VALIDATION_ERROR - invalidObject.html b/packages/errors/__snapshot-html__/CONFIG_VALIDATION_ERROR - invalidObject.html new file mode 100644 index 000000000000..c512125bd392 --- /dev/null +++ b/packages/errors/__snapshot-html__/CONFIG_VALIDATION_ERROR - invalidObject.html @@ -0,0 +1,46 @@ + + + + + + + + + + + +
Your configFile at cypress.json set an invalid value:
+
+Expected defaultCommandTimeout to be a number.
+
+Instead the value was: 
+
+{
+  "foo": "bar"
+}
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/CONFIG_VALIDATION_ERROR - invalidString.html b/packages/errors/__snapshot-html__/CONFIG_VALIDATION_ERROR - invalidString.html new file mode 100644 index 000000000000..cf809bf98794 --- /dev/null +++ b/packages/errors/__snapshot-html__/CONFIG_VALIDATION_ERROR - invalidString.html @@ -0,0 +1,42 @@ + + + + + + + + + + + +
Your configFile at cypress.json set an invalid value:
+
+Expected defaultCommandTimeout to be a number.
+
+Instead the value was: "1234"
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/CONFIG_VALIDATION_ERROR - list.html b/packages/errors/__snapshot-html__/CONFIG_VALIDATION_ERROR - list.html new file mode 100644 index 000000000000..8bb8df4611ed --- /dev/null +++ b/packages/errors/__snapshot-html__/CONFIG_VALIDATION_ERROR - list.html @@ -0,0 +1,50 @@ + + + + + + + + + + + +
Your configFile at cypress.json set an invalid value:
+
+The error occurred while validating the browsers list.
+
+Expected displayName to be a non-empty string.
+
+Instead the value was: 
+
+{
+  "name": "chrome",
+  "version": "1.2.3",
+  "displayName": null
+}
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/CONFIG_VALIDATION_ERROR - noFileType.html b/packages/errors/__snapshot-html__/CONFIG_VALIDATION_ERROR - noFileType.html new file mode 100644 index 000000000000..534dff554fa1 --- /dev/null +++ b/packages/errors/__snapshot-html__/CONFIG_VALIDATION_ERROR - noFileType.html @@ -0,0 +1,42 @@ + + + + + + + + + + + +
An invalid configuration value was set.
+
+Expected defaultCommandTimeout to be a number.
+
+Instead the value was: false
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/CONFIG_VALIDATION_ERROR - pluginsFile.html b/packages/errors/__snapshot-html__/CONFIG_VALIDATION_ERROR - pluginsFile.html new file mode 100644 index 000000000000..8d55d4294883 --- /dev/null +++ b/packages/errors/__snapshot-html__/CONFIG_VALIDATION_ERROR - pluginsFile.html @@ -0,0 +1,42 @@ + + + + + + + + + + + +
Your pluginsFile at cypress/plugins/index.js set an invalid value:
+
+Expected defaultCommandTimeout to be a number.
+
+Instead the value was: false
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/CONFIG_VALIDATION_ERROR.html b/packages/errors/__snapshot-html__/CONFIG_VALIDATION_ERROR.html new file mode 100644 index 000000000000..93838e9fc1b7 --- /dev/null +++ b/packages/errors/__snapshot-html__/CONFIG_VALIDATION_ERROR.html @@ -0,0 +1,42 @@ + + + + + + + + + + + +
Your configFile at cypress.json set an invalid value:
+
+Expected defaultCommandTimeout to be a number.
+
+Instead the value was: false
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/CONFIG_VALIDATION_MSG_ERROR - noFileType.html b/packages/errors/__snapshot-html__/CONFIG_VALIDATION_MSG_ERROR - noFileType.html new file mode 100644 index 000000000000..686eace28b3f --- /dev/null +++ b/packages/errors/__snapshot-html__/CONFIG_VALIDATION_MSG_ERROR - noFileType.html @@ -0,0 +1,40 @@ + + + + + + + + + + + +
An invalid configuration value was set:
+
+`something` was not right
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/CONFIG_VALIDATION_MSG_ERROR.html b/packages/errors/__snapshot-html__/CONFIG_VALIDATION_MSG_ERROR.html new file mode 100644 index 000000000000..bd6b08ad784e --- /dev/null +++ b/packages/errors/__snapshot-html__/CONFIG_VALIDATION_MSG_ERROR.html @@ -0,0 +1,40 @@ + + + + + + + + + + + +
Your configFile as cypress.json set an invalid value:
+
+`something` was not right
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/COULD_NOT_FIND_SYSTEM_NODE.html b/packages/errors/__snapshot-html__/COULD_NOT_FIND_SYSTEM_NODE.html new file mode 100644 index 000000000000..74d37a11d83a --- /dev/null +++ b/packages/errors/__snapshot-html__/COULD_NOT_FIND_SYSTEM_NODE.html @@ -0,0 +1,42 @@ + + + + + + + + + + + +
nodeVersion is set to system but Cypress could not find a usable Node executable on your PATH.
+
+Make sure that your Node executable exists and can be run by the current user.
+
+Cypress will use the built-in Node version 16.2.1 instead.
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/COULD_NOT_PARSE_ARGUMENTS.html b/packages/errors/__snapshot-html__/COULD_NOT_PARSE_ARGUMENTS.html new file mode 100644 index 000000000000..38ab9bc38cf0 --- /dev/null +++ b/packages/errors/__snapshot-html__/COULD_NOT_PARSE_ARGUMENTS.html @@ -0,0 +1,42 @@ + + + + + + + + + + + +
Cypress encountered an error while parsing the argument: --spec
+
+You passed: 1
+
+The error was: spec must be a string or comma-separated list
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/DASHBOARD_ALREADY_COMPLETE.html b/packages/errors/__snapshot-html__/DASHBOARD_ALREADY_COMPLETE.html new file mode 100644 index 000000000000..b1f55d3cf73d --- /dev/null +++ b/packages/errors/__snapshot-html__/DASHBOARD_ALREADY_COMPLETE.html @@ -0,0 +1,47 @@ + + + + + + + + + + + +
The run you are attempting to access is already complete and will not accept new groups.
+
+The existing run is: https://dashboard.cypress.io/project/abcd/runs/1
+
+When a run finishes all of its groups, it waits for a configurable set of time before finally completing. You must add more groups during that time period.
+
+The --group flag you passed was: foo
+The --parallel flag you passed was: true
+
+https://on.cypress.io/already-complete
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/DASHBOARD_API_RESPONSE_FAILED_RETRYING - lastTry.html b/packages/errors/__snapshot-html__/DASHBOARD_API_RESPONSE_FAILED_RETRYING - lastTry.html new file mode 100644 index 000000000000..3851fc91ffdb --- /dev/null +++ b/packages/errors/__snapshot-html__/DASHBOARD_API_RESPONSE_FAILED_RETRYING - lastTry.html @@ -0,0 +1,44 @@ + + + + + + + + + + + +
We encountered an unexpected error talking to our servers.
+
+We will retry 1 more time in 5 seconds...
+
+The server's response was:
+
+StatusCodeError: 500 - "Internal Server Error"
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/DASHBOARD_API_RESPONSE_FAILED_RETRYING.html b/packages/errors/__snapshot-html__/DASHBOARD_API_RESPONSE_FAILED_RETRYING.html new file mode 100644 index 000000000000..8d56bdf9d80d --- /dev/null +++ b/packages/errors/__snapshot-html__/DASHBOARD_API_RESPONSE_FAILED_RETRYING.html @@ -0,0 +1,44 @@ + + + + + + + + + + + +
We encountered an unexpected error talking to our servers.
+
+We will retry 3 more times in 5 seconds...
+
+The server's response was:
+
+StatusCodeError: 500 - "Internal Server Error"
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/DASHBOARD_CANCEL_SKIPPED_SPEC.html b/packages/errors/__snapshot-html__/DASHBOARD_CANCEL_SKIPPED_SPEC.html new file mode 100644 index 000000000000..6d454e3c40b4 --- /dev/null +++ b/packages/errors/__snapshot-html__/DASHBOARD_CANCEL_SKIPPED_SPEC.html @@ -0,0 +1,39 @@ + + + + + + + + + + + +

+  This spec and its tests were skipped because the run has been canceled.
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/DASHBOARD_CANNOT_CREATE_RUN_OR_INSTANCE.html b/packages/errors/__snapshot-html__/DASHBOARD_CANNOT_CREATE_RUN_OR_INSTANCE.html new file mode 100644 index 000000000000..9f34f7c4ad88 --- /dev/null +++ b/packages/errors/__snapshot-html__/DASHBOARD_CANNOT_CREATE_RUN_OR_INSTANCE.html @@ -0,0 +1,44 @@ + + + + + + + + + + + +
Warning: We encountered an error talking to our servers.
+
+This run will not be recorded.
+
+This error will not alter the exit code.
+
+StatusCodeError: 500 - "Internal Server Error"
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/DASHBOARD_CANNOT_PROCEED_IN_PARALLEL.html b/packages/errors/__snapshot-html__/DASHBOARD_CANNOT_PROCEED_IN_PARALLEL.html new file mode 100644 index 000000000000..61a5436cc1c3 --- /dev/null +++ b/packages/errors/__snapshot-html__/DASHBOARD_CANNOT_PROCEED_IN_PARALLEL.html @@ -0,0 +1,47 @@ + + + + + + + + + + + +
We encountered an unexpected error talking to our servers.
+
+Because you passed the --parallel flag, this run cannot proceed because it requires a valid response from our servers.
+
+The --group flag you passed was: foo
+The --ciBuildId flag you passed was: invalid
+
+The server's response was:
+
+StatusCodeError: 500 - "Internal Server Error"
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/DASHBOARD_CANNOT_PROCEED_IN_SERIAL.html b/packages/errors/__snapshot-html__/DASHBOARD_CANNOT_PROCEED_IN_SERIAL.html new file mode 100644 index 000000000000..ad85fcf206d3 --- /dev/null +++ b/packages/errors/__snapshot-html__/DASHBOARD_CANNOT_PROCEED_IN_SERIAL.html @@ -0,0 +1,45 @@ + + + + + + + + + + + +
We encountered an unexpected error talking to our servers.
+
+The --group flag you passed was: foo
+The --ciBuildId flag you passed was: invalid
+
+The server's response was:
+
+StatusCodeError: 500 - "Internal Server Error"
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/DASHBOARD_CANNOT_UPLOAD_RESULTS.html b/packages/errors/__snapshot-html__/DASHBOARD_CANNOT_UPLOAD_RESULTS.html new file mode 100644 index 000000000000..d179c0ff16ea --- /dev/null +++ b/packages/errors/__snapshot-html__/DASHBOARD_CANNOT_UPLOAD_RESULTS.html @@ -0,0 +1,44 @@ + + + + + + + + + + + +
Warning: We encountered an error while uploading results from your run.
+
+These results will not be recorded.
+
+This error will not alter the exit code.
+
+StatusCodeError: 500 - "Internal Server Error"
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/DASHBOARD_INVALID_RUN_REQUEST.html b/packages/errors/__snapshot-html__/DASHBOARD_INVALID_RUN_REQUEST.html new file mode 100644 index 000000000000..d231b57b949f --- /dev/null +++ b/packages/errors/__snapshot-html__/DASHBOARD_INVALID_RUN_REQUEST.html @@ -0,0 +1,55 @@ + + + + + + + + + + + +
Recording this run failed because the request was invalid.
+
+request should follow postRunRequest@2.0.0 schema
+
+Errors:
+
+[
+  "data.commit has additional properties",
+  "data.ci.buildNumber is required"
+]
+
+Request Sent:
+
+{
+  "foo": "foo",
+  "bar": "bar",
+  "baz": "baz"
+}
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/DASHBOARD_PARALLEL_DISALLOWED.html b/packages/errors/__snapshot-html__/DASHBOARD_PARALLEL_DISALLOWED.html new file mode 100644 index 000000000000..23869efd8942 --- /dev/null +++ b/packages/errors/__snapshot-html__/DASHBOARD_PARALLEL_DISALLOWED.html @@ -0,0 +1,47 @@ + + + + + + + + + + + +
You passed the --parallel flag, but this run group was originally created without the --parallel flag.
+
+The existing run is: https://dashboard.cypress.io/project/abcd/runs/1
+
+The --group flag you passed was: foo
+The --parallel flag you passed was: true
+
+You can not use the --parallel flag with this group.
+
+https://on.cypress.io/parallel-disallowed
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/DASHBOARD_PARALLEL_GROUP_PARAMS_MISMATCH.html b/packages/errors/__snapshot-html__/DASHBOARD_PARALLEL_GROUP_PARAMS_MISMATCH.html new file mode 100644 index 000000000000..31c5524e3369 --- /dev/null +++ b/packages/errors/__snapshot-html__/DASHBOARD_PARALLEL_GROUP_PARAMS_MISMATCH.html @@ -0,0 +1,64 @@ + + + + + + + + + + + +
You passed the --parallel flag, but we do not parallelize tests across different environments.
+
+This machine is sending different environment parameters than the first machine that started this parallel run.
+
+The existing run is: https://dashboard.cypress.io/project/abcd/runs/1
+
+In order to run in parallel mode each machine must send identical environment parameters such as:
+
+ - specs
+ - osName
+ - osVersion
+ - browserName
+ - browserVersion (major)
+
+This machine sent the following parameters:
+
+{
+  "osName": "darwin",
+  "osVersion": "v1",
+  "browserName": "Electron",
+  "browserVersion": "59.1.2.3",
+  "specs": [
+    "cypress/integration/app_spec.js"
+  ]
+}
+
+https://on.cypress.io/parallel-group-params-mismatch
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/DASHBOARD_PARALLEL_REQUIRED.html b/packages/errors/__snapshot-html__/DASHBOARD_PARALLEL_REQUIRED.html new file mode 100644 index 000000000000..06bd2f96e0bc --- /dev/null +++ b/packages/errors/__snapshot-html__/DASHBOARD_PARALLEL_REQUIRED.html @@ -0,0 +1,47 @@ + + + + + + + + + + + +
You did not pass the --parallel flag, but this run's group was originally created with the --parallel flag.
+
+The existing run is: https://dashboard.cypress.io/project/abcd/runs/1
+
+The --group flag you passed was: foo
+The --parallel flag you passed was: true
+
+You must use the --parallel flag with this group.
+
+https://on.cypress.io/parallel-required
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/DASHBOARD_PROJECT_NOT_FOUND.html b/packages/errors/__snapshot-html__/DASHBOARD_PROJECT_NOT_FOUND.html new file mode 100644 index 000000000000..7f172da72117 --- /dev/null +++ b/packages/errors/__snapshot-html__/DASHBOARD_PROJECT_NOT_FOUND.html @@ -0,0 +1,48 @@ + + + + + + + + + + + +
We could not find a Dashboard project with the projectId: project-id-123
+
+This projectId came from your /path/to/cypress.json file or an environment variable.
+
+Please log into the Dashboard and find your project.
+
+We will list the correct projectId in the 'Settings' tab.
+
+Alternatively, you can create a new project using the Desktop Application.
+
+https://on.cypress.io/dashboard
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/DASHBOARD_RECORD_KEY_NOT_VALID.html b/packages/errors/__snapshot-html__/DASHBOARD_RECORD_KEY_NOT_VALID.html new file mode 100644 index 000000000000..59ef0c222877 --- /dev/null +++ b/packages/errors/__snapshot-html__/DASHBOARD_RECORD_KEY_NOT_VALID.html @@ -0,0 +1,44 @@ + + + + + + + + + + + +
Your Record Key record-key-123 is not valid with this projectId: project-id-123
+
+It may have been recently revoked by you or another user.
+
+Please log into the Dashboard to see the valid record keys.
+
+https://on.cypress.io/dashboard/projects/project-id-123
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/DASHBOARD_RUN_GROUP_NAME_NOT_UNIQUE.html b/packages/errors/__snapshot-html__/DASHBOARD_RUN_GROUP_NAME_NOT_UNIQUE.html new file mode 100644 index 000000000000..99b1af2c16a5 --- /dev/null +++ b/packages/errors/__snapshot-html__/DASHBOARD_RUN_GROUP_NAME_NOT_UNIQUE.html @@ -0,0 +1,47 @@ + + + + + + + + + + + +
You passed the --group flag, but this group name has already been used for this run.
+
+The existing run is: https://dashboard.cypress.io/project/abcd/runs/1
+
+The --group flag you passed was: foo
+The --parallel flag you passed was: true
+
+If you are trying to parallelize this run, then also pass the --parallel flag, else pass a different group name.
+
+https://on.cypress.io/run-group-name-not-unique
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/DASHBOARD_STALE_RUN.html b/packages/errors/__snapshot-html__/DASHBOARD_STALE_RUN.html new file mode 100644 index 000000000000..8eac4222419b --- /dev/null +++ b/packages/errors/__snapshot-html__/DASHBOARD_STALE_RUN.html @@ -0,0 +1,47 @@ + + + + + + + + + + + +
You are attempting to pass the --parallel flag to a run that was completed over 24 hours ago.
+
+The existing run is: https://dashboard.cypress.io/project/abcd/runs/1
+
+You cannot parallelize a run that has been complete for that long.
+
+The --group flag you passed was: foo
+The --parallel flag you passed was: true
+
+https://on.cypress.io/stale-run
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/DASHBOARD_UNKNOWN_CREATE_RUN_WARNING.html b/packages/errors/__snapshot-html__/DASHBOARD_UNKNOWN_CREATE_RUN_WARNING.html new file mode 100644 index 000000000000..26cb0940387e --- /dev/null +++ b/packages/errors/__snapshot-html__/DASHBOARD_UNKNOWN_CREATE_RUN_WARNING.html @@ -0,0 +1,47 @@ + + + + + + + + + + + +
Warning from Cypress Dashboard: You are almost out of time
+
+Details:
+
+{
+  "code": "OUT_OF_TIME",
+  "name": "OutOfTime",
+  "hadTime": 1000,
+  "spentTime": 999
+}
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/DASHBOARD_UNKNOWN_INVALID_REQUEST.html b/packages/errors/__snapshot-html__/DASHBOARD_UNKNOWN_INVALID_REQUEST.html new file mode 100644 index 000000000000..efd9ce64c704 --- /dev/null +++ b/packages/errors/__snapshot-html__/DASHBOARD_UNKNOWN_INVALID_REQUEST.html @@ -0,0 +1,47 @@ + + + + + + + + + + + +
We encountered an unexpected error talking to our servers.
+
+There is likely something wrong with the request.
+
+The --group flag you passed was: foo
+The --ciBuildId flag you passed was: invalid
+
+The server's response was:
+
+StatusCodeError: 500 - "Internal Server Error"
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/DEPRECATED_BEFORE_BROWSER_LAUNCH_ARGS.html b/packages/errors/__snapshot-html__/DEPRECATED_BEFORE_BROWSER_LAUNCH_ARGS.html new file mode 100644 index 000000000000..91c9b26e8662 --- /dev/null +++ b/packages/errors/__snapshot-html__/DEPRECATED_BEFORE_BROWSER_LAUNCH_ARGS.html @@ -0,0 +1,44 @@ + + + + + + + + + + + +
Deprecation Warning: The before:browser:launch plugin event changed its signature in Cypress version 4.0.0
+
+The event switched from yielding the second argument as an array of browser arguments to an options object with an args property.
+
+We've detected that your code is still using the previous, deprecated interface signature.
+
+This code will not work in a future version of Cypress. Please see the upgrade guide: https://on.cypress.io/deprecated-before-browser-launch-args
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/DUPLICATE_TASK_KEY.html b/packages/errors/__snapshot-html__/DUPLICATE_TASK_KEY.html new file mode 100644 index 000000000000..b06b8fa527ca --- /dev/null +++ b/packages/errors/__snapshot-html__/DUPLICATE_TASK_KEY.html @@ -0,0 +1,44 @@ + + + + + + + + + + + +
Warning: Multiple attempts to register the following task(s):
+
+ - foo
+ - bar
+ - baz
+
+Only the last attempt will be registered.
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/ERROR_READING_FILE.html b/packages/errors/__snapshot-html__/ERROR_READING_FILE.html new file mode 100644 index 000000000000..e31d0f8c0832 --- /dev/null +++ b/packages/errors/__snapshot-html__/ERROR_READING_FILE.html @@ -0,0 +1,42 @@ + + + + + + + + + + + +
Error reading from: /path/to/read/file.ts
+
+Error: fail whale
+    at makeErr (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)
+    at ERROR_READING_FILE (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/ERROR_WRITING_FILE.html b/packages/errors/__snapshot-html__/ERROR_WRITING_FILE.html new file mode 100644 index 000000000000..7d7a875f1cd3 --- /dev/null +++ b/packages/errors/__snapshot-html__/ERROR_WRITING_FILE.html @@ -0,0 +1,42 @@ + + + + + + + + + + + +
Error writing to: /path/to/write/file.ts
+
+Error: fail whale
+    at makeErr (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)
+    at ERROR_WRITING_FILE (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/EXPERIMENTAL_COMPONENT_TESTING_REMOVED.html b/packages/errors/__snapshot-html__/EXPERIMENTAL_COMPONENT_TESTING_REMOVED.html new file mode 100644 index 000000000000..3a9784cc3e03 --- /dev/null +++ b/packages/errors/__snapshot-html__/EXPERIMENTAL_COMPONENT_TESTING_REMOVED.html @@ -0,0 +1,46 @@ + + + + + + + + + + + +
The experimentalComponentTesting configuration option was removed in Cypress version 7.0.0.
+
+Please remove this flag from: /path/to/cypress.config.js
+
+Component Testing is now a standalone command. You can now run your component tests with:
+
+  $ cypress open-ct
+
+https://on.cypress.io/migration-guide
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/EXPERIMENTAL_NETWORK_STUBBING_REMOVED.html b/packages/errors/__snapshot-html__/EXPERIMENTAL_NETWORK_STUBBING_REMOVED.html new file mode 100644 index 000000000000..c127cab16de2 --- /dev/null +++ b/packages/errors/__snapshot-html__/EXPERIMENTAL_NETWORK_STUBBING_REMOVED.html @@ -0,0 +1,40 @@ + + + + + + + + + + + +
The experimentalNetworkStubbing configuration option was removed in Cypress version 6.0.0.
+
+It is no longer necessary for using cy.intercept(). You can safely remove this option from your config.
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/EXPERIMENTAL_RUN_EVENTS_REMOVED.html b/packages/errors/__snapshot-html__/EXPERIMENTAL_RUN_EVENTS_REMOVED.html new file mode 100644 index 000000000000..d16b743fd4c9 --- /dev/null +++ b/packages/errors/__snapshot-html__/EXPERIMENTAL_RUN_EVENTS_REMOVED.html @@ -0,0 +1,40 @@ + + + + + + + + + + + +
The experimentalRunEvents configuration option was removed in Cypress version 6.7.0. It is no longer necessary when listening to run events in the plugins file.
+
+You can safely remove this option from your config.
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/EXPERIMENTAL_SAMESITE_REMOVED.html b/packages/errors/__snapshot-html__/EXPERIMENTAL_SAMESITE_REMOVED.html new file mode 100644 index 000000000000..1aa0127b6c23 --- /dev/null +++ b/packages/errors/__snapshot-html__/EXPERIMENTAL_SAMESITE_REMOVED.html @@ -0,0 +1,42 @@ + + + + + + + + + + + +
The experimentalGetCookiesSameSite configuration option was removed in Cypress version 5.0.0.
+
+Returning the sameSite property is now the default behavior of the cy.cookie commands.
+
+You can safely remove this option from your config.
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/EXPERIMENTAL_SHADOW_DOM_REMOVED.html b/packages/errors/__snapshot-html__/EXPERIMENTAL_SHADOW_DOM_REMOVED.html new file mode 100644 index 000000000000..383ed62ad20b --- /dev/null +++ b/packages/errors/__snapshot-html__/EXPERIMENTAL_SHADOW_DOM_REMOVED.html @@ -0,0 +1,40 @@ + + + + + + + + + + + +
The experimentalShadowDomSupport configuration option was removed in Cypress version 5.2.0. It is no longer necessary when utilizing the includeShadowDom option.
+
+You can safely remove this option from your config.
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/EXTENSION_NOT_LOADED.html b/packages/errors/__snapshot-html__/EXTENSION_NOT_LOADED.html new file mode 100644 index 000000000000..2ab036e3f05b --- /dev/null +++ b/packages/errors/__snapshot-html__/EXTENSION_NOT_LOADED.html @@ -0,0 +1,40 @@ + + + + + + + + + + + +
Electron could not install the extension at path: /path/to/extension
+
+Please verify that this is the path to a valid, unpacked WebExtension.
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/FIREFOX_COULD_NOT_CONNECT.html b/packages/errors/__snapshot-html__/FIREFOX_COULD_NOT_CONNECT.html new file mode 100644 index 000000000000..3eea972eca09 --- /dev/null +++ b/packages/errors/__snapshot-html__/FIREFOX_COULD_NOT_CONNECT.html @@ -0,0 +1,44 @@ + + + + + + + + + + + +
Cypress failed to make a connection to Firefox.
+
+This usually indicates there was a problem opening the Firefox browser.
+
+Error: fail whale
+    at makeErr (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)
+    at FIREFOX_COULD_NOT_CONNECT (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/FIREFOX_GC_INTERVAL_REMOVED.html b/packages/errors/__snapshot-html__/FIREFOX_GC_INTERVAL_REMOVED.html new file mode 100644 index 000000000000..19925cc65c91 --- /dev/null +++ b/packages/errors/__snapshot-html__/FIREFOX_GC_INTERVAL_REMOVED.html @@ -0,0 +1,42 @@ + + + + + + + + + + + +
The firefoxGcInterval configuration option was removed in Cypress version 8.0.0. It was introduced to work around a bug in Firefox 79 and below.
+
+Since Cypress no longer supports Firefox 85 and below in Cypress Cypress version 8.0.0, this option was removed.
+
+You can safely remove this option from your config.
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/FIREFOX_MARIONETTE_FAILURE.html b/packages/errors/__snapshot-html__/FIREFOX_MARIONETTE_FAILURE.html new file mode 100644 index 000000000000..6bbfcca54418 --- /dev/null +++ b/packages/errors/__snapshot-html__/FIREFOX_MARIONETTE_FAILURE.html @@ -0,0 +1,46 @@ + + + + + + + + + + + +
Cypress could not connect to Firefox.
+
+An unexpected error was received from Marionette: connection
+
+To avoid this error, ensure that there are no other instances of Firefox launched by Cypress running.
+
+Error: fail whale
+    at makeErr (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)
+    at FIREFOX_MARIONETTE_FAILURE (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/FIXTURE_NOT_FOUND.html b/packages/errors/__snapshot-html__/FIXTURE_NOT_FOUND.html new file mode 100644 index 000000000000..76c7820e7db0 --- /dev/null +++ b/packages/errors/__snapshot-html__/FIXTURE_NOT_FOUND.html @@ -0,0 +1,47 @@ + + + + + + + + + + + +
A fixture file could not be found at any of the following paths:
+
+    > file
+    > file.[ext]
+
+Cypress looked for these file extensions at the provided path:
+
+    > js, ts, json
+
+Provide a path to an existing fixture file.
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/FOLDER_NOT_WRITABLE.html b/packages/errors/__snapshot-html__/FOLDER_NOT_WRITABLE.html new file mode 100644 index 000000000000..b76f5c1849c5 --- /dev/null +++ b/packages/errors/__snapshot-html__/FOLDER_NOT_WRITABLE.html @@ -0,0 +1,44 @@ + + + + + + + + + + + +
This folder is not writable: /path/to/folder
+
+Writing to this directory is required by Cypress in order to store screenshots and videos.
+
+Enable write permissions to this directory to ensure screenshots and videos are stored.
+
+If you don't require screenshots or videos to be stored you can safely ignore this warning.
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/FREE_PLAN_EXCEEDS_MONTHLY_PRIVATE_TESTS.html b/packages/errors/__snapshot-html__/FREE_PLAN_EXCEEDS_MONTHLY_PRIVATE_TESTS.html new file mode 100644 index 000000000000..d87c629efd39 --- /dev/null +++ b/packages/errors/__snapshot-html__/FREE_PLAN_EXCEEDS_MONTHLY_PRIVATE_TESTS.html @@ -0,0 +1,42 @@ + + + + + + + + + + + +
You've exceeded the limit of private test results under your free plan this month. The limit is 500 test results.
+
+To continue recording tests this month you must upgrade your account. Please visit your billing to upgrade to another billing plan.
+
+https://dashboard.cypress.io/project/abcd
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/FREE_PLAN_EXCEEDS_MONTHLY_TESTS.html b/packages/errors/__snapshot-html__/FREE_PLAN_EXCEEDS_MONTHLY_TESTS.html new file mode 100644 index 000000000000..d2d1d791177d --- /dev/null +++ b/packages/errors/__snapshot-html__/FREE_PLAN_EXCEEDS_MONTHLY_TESTS.html @@ -0,0 +1,42 @@ + + + + + + + + + + + +
You've exceeded the limit of test results under your free plan this month. The limit is 500 test results.
+
+To continue recording tests this month you must upgrade your account. Please visit your billing to upgrade to another billing plan.
+
+https://on.cypress.io/set-up-billing
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/FREE_PLAN_IN_GRACE_PERIOD_EXCEEDS_MONTHLY_PRIVATE_TESTS.html b/packages/errors/__snapshot-html__/FREE_PLAN_IN_GRACE_PERIOD_EXCEEDS_MONTHLY_PRIVATE_TESTS.html new file mode 100644 index 000000000000..f828ad90b96c --- /dev/null +++ b/packages/errors/__snapshot-html__/FREE_PLAN_IN_GRACE_PERIOD_EXCEEDS_MONTHLY_PRIVATE_TESTS.html @@ -0,0 +1,42 @@ + + + + + + + + + + + +
You've exceeded the limit of private test results under your free plan this month. The limit is 500 test results.
+
+Your plan is now in a grace period, which means your tests will still be recorded until the grace period ends. Please upgrade your plan to continue recording tests on the Cypress Dashboard in the future.
+
+https://dashboard.cypress.io/project/abcd
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/FREE_PLAN_IN_GRACE_PERIOD_EXCEEDS_MONTHLY_TESTS.html b/packages/errors/__snapshot-html__/FREE_PLAN_IN_GRACE_PERIOD_EXCEEDS_MONTHLY_TESTS.html new file mode 100644 index 000000000000..4fab940d27b4 --- /dev/null +++ b/packages/errors/__snapshot-html__/FREE_PLAN_IN_GRACE_PERIOD_EXCEEDS_MONTHLY_TESTS.html @@ -0,0 +1,44 @@ + + + + + + + + + + + +
You've exceeded the limit of test results under your free plan this month. The limit is 500 test results.
+
+Your plan is now in a grace period, which means you will have the full benefits of your current plan until Feb 1, 2022.
+
+Please visit your billing to upgrade your plan.
+
+https://on.cypress.io/set-up-billing
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/FREE_PLAN_IN_GRACE_PERIOD_PARALLEL_FEATURE.html b/packages/errors/__snapshot-html__/FREE_PLAN_IN_GRACE_PERIOD_PARALLEL_FEATURE.html new file mode 100644 index 000000000000..16acdd16cf39 --- /dev/null +++ b/packages/errors/__snapshot-html__/FREE_PLAN_IN_GRACE_PERIOD_PARALLEL_FEATURE.html @@ -0,0 +1,42 @@ + + + + + + + + + + + +
Parallelization is not included under your free plan.
+
+Your plan is now in a grace period, which means your tests will still run in parallel until Feb 1, 2022. Please upgrade your plan to continue running your tests in parallel in the future.
+
+https://on.cypress.io/set-up-billing
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/INCOMPATIBLE_PLUGIN_RETRIES.html b/packages/errors/__snapshot-html__/INCOMPATIBLE_PLUGIN_RETRIES.html new file mode 100644 index 000000000000..6b1a26de534d --- /dev/null +++ b/packages/errors/__snapshot-html__/INCOMPATIBLE_PLUGIN_RETRIES.html @@ -0,0 +1,45 @@ + + + + + + + + + + + +
We've detected that the incompatible plugin cypress-plugin-retries is installed at: ./path/to/cypress-plugin-retries
+
+Test retries is now natively supported in Cypress version 5.0.0.
+
+Remove the plugin from your dependencies to silence this warning.
+
+https://on.cypress.io/test-retries
+
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/INCORRECT_CI_BUILD_ID_USAGE.html b/packages/errors/__snapshot-html__/INCORRECT_CI_BUILD_ID_USAGE.html new file mode 100644 index 000000000000..1cf399ad14b2 --- /dev/null +++ b/packages/errors/__snapshot-html__/INCORRECT_CI_BUILD_ID_USAGE.html @@ -0,0 +1,44 @@ + + + + + + + + + + + +
You passed the --ci-build-id flag but did not provide either a --group or --parallel flag.
+
+The --ci-build-id flag you passed was: ciBuildId123
+
+The --ci-build-id flag is used to either group or parallelize multiple runs together.
+
+https://on.cypress.io/incorrect-ci-build-id-usage
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/INDETERMINATE_CI_BUILD_ID.html b/packages/errors/__snapshot-html__/INDETERMINATE_CI_BUILD_ID.html new file mode 100644 index 000000000000..e5e81e635832 --- /dev/null +++ b/packages/errors/__snapshot-html__/INDETERMINATE_CI_BUILD_ID.html @@ -0,0 +1,73 @@ + + + + + + + + + + + +
You passed the --group or --parallel flag but we could not automatically determine or generate a ciBuildId.
+
+The --group flag you passed was: foo
+The --parallel flag you passed was: false
+
+In order to use either of these features a ciBuildId must be determined.
+
+The ciBuildId is automatically detected if you are running Cypress in any of the these CI providers:
+
+ - appveyor
+ - azure
+ - awsCodeBuild
+ - bamboo
+ - bitbucket
+ - buildkite
+ - circle
+ - codeshipBasic
+ - codeshipPro
+ - concourse
+ - codeFresh
+ - drone
+ - githubActions
+ - gitlab
+ - goCD
+ - googleCloud
+ - jenkins
+ - semaphore
+ - shippable
+ - teamfoundation
+ - travis
+ - netlify
+ - layerci
+
+Because the ciBuildId could not be auto-detected you must pass the --ci-build-id flag manually.
+
+https://on.cypress.io/indeterminate-ci-build-id
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/INVALID_CONFIG_OPTION - plural.html b/packages/errors/__snapshot-html__/INVALID_CONFIG_OPTION - plural.html new file mode 100644 index 000000000000..56233ce5858f --- /dev/null +++ b/packages/errors/__snapshot-html__/INVALID_CONFIG_OPTION - plural.html @@ -0,0 +1,44 @@ + + + + + + + + + + + +
The following configuration options are invalid:
+
+ - foo
+ - bar
+
+https://on.cypress.io/configuration
+
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/INVALID_CONFIG_OPTION.html b/packages/errors/__snapshot-html__/INVALID_CONFIG_OPTION.html new file mode 100644 index 000000000000..ae37189fd589 --- /dev/null +++ b/packages/errors/__snapshot-html__/INVALID_CONFIG_OPTION.html @@ -0,0 +1,43 @@ + + + + + + + + + + + +
The following configuration option is invalid:
+
+ - foo
+
+https://on.cypress.io/configuration
+
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/INVALID_CYPRESS_INTERNAL_ENV.html b/packages/errors/__snapshot-html__/INVALID_CYPRESS_INTERNAL_ENV.html new file mode 100644 index 000000000000..10693665d813 --- /dev/null +++ b/packages/errors/__snapshot-html__/INVALID_CYPRESS_INTERNAL_ENV.html @@ -0,0 +1,40 @@ + + + + + + + + + + + +
We have detected an unknown or unsupported CYPRESS_INTERNAL_ENV value: foo
+
+CYPRESS_INTERNAL_ENV is reserved for internal use and cannot be modified.
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/INVALID_REPORTER_NAME.html b/packages/errors/__snapshot-html__/INVALID_REPORTER_NAME.html new file mode 100644 index 000000000000..bfc4e5903019 --- /dev/null +++ b/packages/errors/__snapshot-html__/INVALID_REPORTER_NAME.html @@ -0,0 +1,49 @@ + + + + + + + + + + + +
Error loading the reporter: missing-reporter-name
+
+We searched for the reporter in these paths:
+
+ - /path/to/reporter
+ - /path/reporter
+
+Learn more at https://on.cypress.io/reporters
+
+Error: fail whale
+    at makeErr (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)
+    at INVALID_REPORTER_NAME (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/INVOKED_BINARY_OUTSIDE_NPM_MODULE.html b/packages/errors/__snapshot-html__/INVOKED_BINARY_OUTSIDE_NPM_MODULE.html new file mode 100644 index 000000000000..5246b2581724 --- /dev/null +++ b/packages/errors/__snapshot-html__/INVOKED_BINARY_OUTSIDE_NPM_MODULE.html @@ -0,0 +1,44 @@ + + + + + + + + + + + +
It looks like you are running the Cypress binary directly.
+
+This is not the recommended approach, and Cypress may not work correctly.
+
+Please install the cypress NPM package and follow the instructions here:
+
+https://on.cypress.io/installing-cypress
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/LEGACY_CONFIG_FILE.html b/packages/errors/__snapshot-html__/LEGACY_CONFIG_FILE.html new file mode 100644 index 000000000000..2b8e82ac8afe --- /dev/null +++ b/packages/errors/__snapshot-html__/LEGACY_CONFIG_FILE.html @@ -0,0 +1,43 @@ + + + + + + + + + + + +
There is both a cypress.json and a cypress.json file at the location below:
+
+/path/to/projectRoot
+
+Cypress no longer supports cypress.json, please remove it from your project.
+
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/MULTIPLE_SUPPORT_FILES_FOUND.html b/packages/errors/__snapshot-html__/MULTIPLE_SUPPORT_FILES_FOUND.html new file mode 100644 index 000000000000..b7457c85870b --- /dev/null +++ b/packages/errors/__snapshot-html__/MULTIPLE_SUPPORT_FILES_FOUND.html @@ -0,0 +1,47 @@ + + + + + + + + + + + +
There were multiple support files found matching your supportFile pattern.
+
+Your supportFile is set to: spec.{ts,js}
+
+We found the following files:
+
+ - support.ts
+ - support.js
+
+Please remove or combine the support files into a single file.
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/NODE_VERSION_DEPRECATION_BUNDLED.html b/packages/errors/__snapshot-html__/NODE_VERSION_DEPRECATION_BUNDLED.html new file mode 100644 index 000000000000..2ae1e6cfc1ad --- /dev/null +++ b/packages/errors/__snapshot-html__/NODE_VERSION_DEPRECATION_BUNDLED.html @@ -0,0 +1,45 @@ + + + + + + + + + + + +
Deprecation Warning: nodeVersion is currently set to bundled in the cypress.json configuration file.
+
+As of Cypress version 9.0.0 the default behavior of nodeVersion has changed to always use the version of Node used to start cypress via the cli.
+
+When nodeVersion is set to bundled, Cypress will use the version of Node bundled with electron. This can cause problems running certain plugins or integrations.
+
+As the nodeVersion configuration option will be removed in a future release, it is recommended to remove the nodeVersion configuration option from cypress.json.
+
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/NODE_VERSION_DEPRECATION_SYSTEM.html b/packages/errors/__snapshot-html__/NODE_VERSION_DEPRECATION_SYSTEM.html new file mode 100644 index 000000000000..528bc1d53bbf --- /dev/null +++ b/packages/errors/__snapshot-html__/NODE_VERSION_DEPRECATION_SYSTEM.html @@ -0,0 +1,43 @@ + + + + + + + + + + + +
Deprecation Warning: nodeVersion is currently set to system in the cypress.json configuration file.
+
+As of Cypress version 9.0.0 the default behavior of nodeVersion has changed to always use the version of Node used to start cypress via the cli.
+
+Please remove the nodeVersion configuration option from cypress.json.
+
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/NOT_LOGGED_IN.html b/packages/errors/__snapshot-html__/NOT_LOGGED_IN.html new file mode 100644 index 000000000000..ac98f99b559a --- /dev/null +++ b/packages/errors/__snapshot-html__/NOT_LOGGED_IN.html @@ -0,0 +1,40 @@ + + + + + + + + + + + +
You're not logged in.
+
+Run cypress open to open the Desktop App and log in.
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/NO_DEFAULT_CONFIG_FILE_FOUND.html b/packages/errors/__snapshot-html__/NO_DEFAULT_CONFIG_FILE_FOUND.html new file mode 100644 index 000000000000..227513bc9861 --- /dev/null +++ b/packages/errors/__snapshot-html__/NO_DEFAULT_CONFIG_FILE_FOUND.html @@ -0,0 +1,38 @@ + + + + + + + + + + + +
Could not find a Cypress configuration file in this folder: /path/to/project/root
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/NO_PROJECT_FOUND_AT_PROJECT_ROOT.html b/packages/errors/__snapshot-html__/NO_PROJECT_FOUND_AT_PROJECT_ROOT.html new file mode 100644 index 000000000000..8b241e509dbf --- /dev/null +++ b/packages/errors/__snapshot-html__/NO_PROJECT_FOUND_AT_PROJECT_ROOT.html @@ -0,0 +1,38 @@ + + + + + + + + + + + +
Can't find a project at the path: /path/to/project
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/NO_PROJECT_ID.html b/packages/errors/__snapshot-html__/NO_PROJECT_ID.html new file mode 100644 index 000000000000..971dabfdcf6a --- /dev/null +++ b/packages/errors/__snapshot-html__/NO_PROJECT_ID.html @@ -0,0 +1,38 @@ + + + + + + + + + + + +
Can't find projectId in the config file: /path/to/project/cypress.json
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/NO_SPECS_FOUND - arrPattern.html b/packages/errors/__snapshot-html__/NO_SPECS_FOUND - arrPattern.html new file mode 100644 index 000000000000..60f4f7f4756b --- /dev/null +++ b/packages/errors/__snapshot-html__/NO_SPECS_FOUND - arrPattern.html @@ -0,0 +1,43 @@ + + + + + + + + + + + +
Can't run because no spec files were found.
+
+We searched for specs matching these glob patterns:
+
+  > /path/to/project/root/**_spec.js
+  > /path/to/project/root/**/*.cy.*
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/NO_SPECS_FOUND - noPattern.html b/packages/errors/__snapshot-html__/NO_SPECS_FOUND - noPattern.html new file mode 100644 index 000000000000..fe4467703999 --- /dev/null +++ b/packages/errors/__snapshot-html__/NO_SPECS_FOUND - noPattern.html @@ -0,0 +1,42 @@ + + + + + + + + + + + +
Can't run because no spec files were found.
+
+We searched for specs inside of this folder:
+
+  > /path/to/project/root
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/NO_SPECS_FOUND - pathCommonPattern.html b/packages/errors/__snapshot-html__/NO_SPECS_FOUND - pathCommonPattern.html new file mode 100644 index 000000000000..b2d4c57aaf6e --- /dev/null +++ b/packages/errors/__snapshot-html__/NO_SPECS_FOUND - pathCommonPattern.html @@ -0,0 +1,43 @@ + + + + + + + + + + + +
Can't run because no spec files were found.
+
+We searched for specs matching these glob patterns:
+
+  > /path/to/project/**_spec.js
+  > /path/to/project/**/*.cy.*
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/NO_SPECS_FOUND - pathNoCommonPattern.html b/packages/errors/__snapshot-html__/NO_SPECS_FOUND - pathNoCommonPattern.html new file mode 100644 index 000000000000..c582cafae9c1 --- /dev/null +++ b/packages/errors/__snapshot-html__/NO_SPECS_FOUND - pathNoCommonPattern.html @@ -0,0 +1,42 @@ + + + + + + + + + + + +
Can't run because no spec files were found.
+
+We searched for specs matching this glob pattern:
+
+  > /foo/*_spec.js
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/NO_SPECS_FOUND.html b/packages/errors/__snapshot-html__/NO_SPECS_FOUND.html new file mode 100644 index 000000000000..f3438520314a --- /dev/null +++ b/packages/errors/__snapshot-html__/NO_SPECS_FOUND.html @@ -0,0 +1,42 @@ + + + + + + + + + + + +
Can't run because no spec files were found.
+
+We searched for specs matching this glob pattern:
+
+  > /path/to/project/root/**_spec.js
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/PAID_PLAN_EXCEEDS_MONTHLY_PRIVATE_TESTS.html b/packages/errors/__snapshot-html__/PAID_PLAN_EXCEEDS_MONTHLY_PRIVATE_TESTS.html new file mode 100644 index 000000000000..0c434815d3fc --- /dev/null +++ b/packages/errors/__snapshot-html__/PAID_PLAN_EXCEEDS_MONTHLY_PRIVATE_TESTS.html @@ -0,0 +1,42 @@ + + + + + + + + + + + +
You've exceeded the limit of private test results under your current billing plan this month. The limit is 25000 private test results.
+
+To upgrade your account, please visit your billing to upgrade to another billing plan.
+
+https://on.cypress.io/set-up-billing
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/PARALLEL_FEATURE_NOT_AVAILABLE_IN_PLAN.html b/packages/errors/__snapshot-html__/PARALLEL_FEATURE_NOT_AVAILABLE_IN_PLAN.html new file mode 100644 index 000000000000..1cb817fc1d87 --- /dev/null +++ b/packages/errors/__snapshot-html__/PARALLEL_FEATURE_NOT_AVAILABLE_IN_PLAN.html @@ -0,0 +1,42 @@ + + + + + + + + + + + +
Parallelization is not included under your current billing plan.
+
+To run your tests in parallel, please visit your billing and upgrade to another plan with parallelization.
+
+https://on.cypress.io/set-up-billing
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/PLAN_EXCEEDS_MONTHLY_TESTS.html b/packages/errors/__snapshot-html__/PLAN_EXCEEDS_MONTHLY_TESTS.html new file mode 100644 index 000000000000..15297714defc --- /dev/null +++ b/packages/errors/__snapshot-html__/PLAN_EXCEEDS_MONTHLY_TESTS.html @@ -0,0 +1,42 @@ + + + + + + + + + + + +
You've exceeded the limit of test results under your Sprout billing plan this month. The limit is 25000 test results.
+
+To continue getting the full benefits of your current plan, please visit your billing to upgrade.
+
+https://on.cypress.io/set-up-billing
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/PLAN_IN_GRACE_PERIOD_RUN_GROUPING_FEATURE_USED.html b/packages/errors/__snapshot-html__/PLAN_IN_GRACE_PERIOD_RUN_GROUPING_FEATURE_USED.html new file mode 100644 index 000000000000..9887d810545e --- /dev/null +++ b/packages/errors/__snapshot-html__/PLAN_IN_GRACE_PERIOD_RUN_GROUPING_FEATURE_USED.html @@ -0,0 +1,42 @@ + + + + + + + + + + + +
Grouping is not included under your free plan.
+
+Your plan is now in a grace period, which means your tests will still run with groups until Feb 1, 2022. Please upgrade your plan to continue running your tests with groups in the future.
+
+https://on.cypress.io/set-up-billing
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/PLUGINS_INVALID_EVENT_NAME_ERROR.html b/packages/errors/__snapshot-html__/PLUGINS_INVALID_EVENT_NAME_ERROR.html new file mode 100644 index 000000000000..896c3a8855ee --- /dev/null +++ b/packages/errors/__snapshot-html__/PLUGINS_INVALID_EVENT_NAME_ERROR.html @@ -0,0 +1,52 @@ + + + + + + + + + + + +
Your configFile threw a validation error from: /path/to/cypress.config.js
+
+You must pass a valid event name when registering a plugin.
+
+You passed: invalid:event
+
+The following are valid events:
+
+ - foo
+ - bar
+ - baz
+
+Error: fail whale
+    at makeErr (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)
+    at PLUGINS_INVALID_EVENT_NAME_ERROR (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/PLUGINS_RUN_EVENT_ERROR.html b/packages/errors/__snapshot-html__/PLUGINS_RUN_EVENT_ERROR.html new file mode 100644 index 000000000000..6d55ed6b054c --- /dev/null +++ b/packages/errors/__snapshot-html__/PLUGINS_RUN_EVENT_ERROR.html @@ -0,0 +1,44 @@ + + + + + + + + + + + +
An error was thrown in your plugins file while executing the handler for the before:spec event.
+
+The error we received was:
+
+Error: fail whale
+    at makeErr (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)
+    at PLUGINS_RUN_EVENT_ERROR (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/PORT_IN_USE_LONG.html b/packages/errors/__snapshot-html__/PORT_IN_USE_LONG.html new file mode 100644 index 000000000000..8a43571d3fc1 --- /dev/null +++ b/packages/errors/__snapshot-html__/PORT_IN_USE_LONG.html @@ -0,0 +1,40 @@ + + + + + + + + + + + +
Can't run project because port is currently in use: 2020
+
+Assign a different port with the --port <port> argument or shut down the other running process.
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/PORT_IN_USE_SHORT.html b/packages/errors/__snapshot-html__/PORT_IN_USE_SHORT.html new file mode 100644 index 000000000000..d5bf44ec55a4 --- /dev/null +++ b/packages/errors/__snapshot-html__/PORT_IN_USE_SHORT.html @@ -0,0 +1,38 @@ + + + + + + + + + + + +
Port 2020 is already in use.
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/PROJECT_ID_AND_KEY_BUT_MISSING_RECORD_OPTION.html b/packages/errors/__snapshot-html__/PROJECT_ID_AND_KEY_BUT_MISSING_RECORD_OPTION.html new file mode 100644 index 000000000000..a51bae399d44 --- /dev/null +++ b/packages/errors/__snapshot-html__/PROJECT_ID_AND_KEY_BUT_MISSING_RECORD_OPTION.html @@ -0,0 +1,54 @@ + + + + + + + + + + + +
This project has been configured to record runs on our Dashboard.
+
+It currently has the projectId: project-id-123
+
+You also provided your Record Key, but you did not pass the --record flag.
+
+This run will not be recorded.
+
+If you meant to have this run recorded please additionally pass this flag:
+
+  $ cypress run --record
+
+If you don't want to record these runs, you can silence this warning:
+
+  $ cypress run --record false
+
+https://on.cypress.io/recording-project-runs
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/RECORDING_FROM_FORK_PR.html b/packages/errors/__snapshot-html__/RECORDING_FROM_FORK_PR.html new file mode 100644 index 000000000000..9b5793382784 --- /dev/null +++ b/packages/errors/__snapshot-html__/RECORDING_FROM_FORK_PR.html @@ -0,0 +1,44 @@ + + + + + + + + + + + +
Warning: It looks like you are trying to record this run from a forked PR.
+
+The Record Key is missing. Your CI provider is likely not passing private environment variables to builds from forks.
+
+These results will not be recorded.
+
+This error will not alter the exit code.
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/RECORD_KEY_MISSING.html b/packages/errors/__snapshot-html__/RECORD_KEY_MISSING.html new file mode 100644 index 000000000000..b72f6fb5c6cc --- /dev/null +++ b/packages/errors/__snapshot-html__/RECORD_KEY_MISSING.html @@ -0,0 +1,46 @@ + + + + + + + + + + + +
You passed the --record flag but did not provide us your Record Key.
+
+You can pass us your Record Key like this:
+
+  $ cypress run --record --key <record_key>
+
+You can also set the key as an environment variable with the name: CYPRESS_RECORD_KEY
+
+https://on.cypress.io/how-do-i-record-runs
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/RECORD_PARAMS_WITHOUT_RECORDING.html b/packages/errors/__snapshot-html__/RECORD_PARAMS_WITHOUT_RECORDING.html new file mode 100644 index 000000000000..a2e297e1e4dc --- /dev/null +++ b/packages/errors/__snapshot-html__/RECORD_PARAMS_WITHOUT_RECORDING.html @@ -0,0 +1,44 @@ + + + + + + + + + + + +
You passed the --ci-build-id, --group, --tag, or --parallel flag without also passing the --record flag.
+
+The --parallel flag you passed was: true
+
+These flags can only be used when recording to the Cypress Dashboard service.
+
+https://on.cypress.io/record-params-without-recording
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/RENAMED_CONFIG_OPTION.html b/packages/errors/__snapshot-html__/RENAMED_CONFIG_OPTION.html new file mode 100644 index 000000000000..79d90cf30b52 --- /dev/null +++ b/packages/errors/__snapshot-html__/RENAMED_CONFIG_OPTION.html @@ -0,0 +1,40 @@ + + + + + + + + + + + +
The oldName configuration option you have supplied has been renamed.
+
+Please rename oldName to newName
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/RENDERER_CRASHED.html b/packages/errors/__snapshot-html__/RENDERER_CRASHED.html new file mode 100644 index 000000000000..e3912fc901d3 --- /dev/null +++ b/packages/errors/__snapshot-html__/RENDERER_CRASHED.html @@ -0,0 +1,54 @@ + + + + + + + + + + + +
We detected that the Chromium Renderer process just crashed.
+
+This is the equivalent to seeing the 'sad face' when Chrome dies.
+
+This can happen for a number of different reasons:
+
+- You wrote an endless loop and you must fix your own code
+- There is a memory leak in Cypress (unlikely but possible)
+- You are running Docker (there is an easy fix for this: see link below)
+- You are running lots of tests on a memory intense application
+- You are running in a memory starved VM environment
+- There are problems with your GPU / GPU drivers
+- There are browser bugs in Chromium
+
+You can learn more including how to fix Docker here:
+
+https://on.cypress.io/renderer-process-crashed
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/RUN_GROUPING_FEATURE_NOT_AVAILABLE_IN_PLAN.html b/packages/errors/__snapshot-html__/RUN_GROUPING_FEATURE_NOT_AVAILABLE_IN_PLAN.html new file mode 100644 index 000000000000..230f7a2cfa91 --- /dev/null +++ b/packages/errors/__snapshot-html__/RUN_GROUPING_FEATURE_NOT_AVAILABLE_IN_PLAN.html @@ -0,0 +1,42 @@ + + + + + + + + + + + +
Grouping is not included under your current billing plan.
+
+To run your tests with groups, please visit your billing and upgrade to another plan with grouping.
+
+https://on.cypress.io/set-up-billing
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/SETUP_NODE_EVENTS_DO_NOT_SUPPORT_DEV_SERVER.html b/packages/errors/__snapshot-html__/SETUP_NODE_EVENTS_DO_NOT_SUPPORT_DEV_SERVER.html new file mode 100644 index 000000000000..d1596bcbf224 --- /dev/null +++ b/packages/errors/__snapshot-html__/SETUP_NODE_EVENTS_DO_NOT_SUPPORT_DEV_SERVER.html @@ -0,0 +1,52 @@ + + + + + + + + + + + +
Your configFile is invalid: /path/to/project/cypress.config.js
+
+Binding to the on('dev-server:start') event is no longer necessary.
+
+Please update your code to use the component.devServer() function.
+
+{
+  component: {
+    devServer (cypressDevServerConfig, devServerConfig) {
+      // start dev server here
+  }
+}
+
+Learn more: https://on.cypress.io/dev-server
+
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/SETUP_NODE_EVENTS_IS_NOT_FUNCTION - array.html b/packages/errors/__snapshot-html__/SETUP_NODE_EVENTS_IS_NOT_FUNCTION - array.html new file mode 100644 index 000000000000..3238c7d9134f --- /dev/null +++ b/packages/errors/__snapshot-html__/SETUP_NODE_EVENTS_IS_NOT_FUNCTION - array.html @@ -0,0 +1,58 @@ + + + + + + + + + + + +
Your configFile is invalid: /path/to/cypress.config.js
+
+The component.setupNodeEvents() function must be defined with the following signature:
+
+{
+  component: {
+    setupNodeEvents(on, config) {
+      // configure tasks and plugins here
+    }
+  }
+}
+
+Instead we saw:
+
+[
+  "some",
+  "array"
+]
+
+https://on.cypress.io/plugins-api
+
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/SETUP_NODE_EVENTS_IS_NOT_FUNCTION - string.html b/packages/errors/__snapshot-html__/SETUP_NODE_EVENTS_IS_NOT_FUNCTION - string.html new file mode 100644 index 000000000000..3ee76bf23e04 --- /dev/null +++ b/packages/errors/__snapshot-html__/SETUP_NODE_EVENTS_IS_NOT_FUNCTION - string.html @@ -0,0 +1,55 @@ + + + + + + + + + + + +
Your configFile is invalid: /path/to/cypress.config.js
+
+The component.setupNodeEvents() function must be defined with the following signature:
+
+{
+  component: {
+    setupNodeEvents(on, config) {
+      // configure tasks and plugins here
+    }
+  }
+}
+
+Instead we saw:
+
+"some string"
+
+https://on.cypress.io/plugins-api
+
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/SETUP_NODE_EVENTS_IS_NOT_FUNCTION.html b/packages/errors/__snapshot-html__/SETUP_NODE_EVENTS_IS_NOT_FUNCTION.html new file mode 100644 index 000000000000..3f66cb084e54 --- /dev/null +++ b/packages/errors/__snapshot-html__/SETUP_NODE_EVENTS_IS_NOT_FUNCTION.html @@ -0,0 +1,57 @@ + + + + + + + + + + + +
Your configFile is invalid: /path/to/cypress.config.js
+
+The e2e.setupNodeEvents() function must be defined with the following signature:
+
+{
+  e2e: {
+    setupNodeEvents(on, config) {
+      // configure tasks and plugins here
+    }
+  }
+}
+
+Instead we saw:
+
+{
+  "some": "object"
+}
+
+https://on.cypress.io/plugins-api
+
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/SUPPORT_FILE_NOT_FOUND.html b/packages/errors/__snapshot-html__/SUPPORT_FILE_NOT_FOUND.html new file mode 100644 index 000000000000..02c22756067e --- /dev/null +++ b/packages/errors/__snapshot-html__/SUPPORT_FILE_NOT_FOUND.html @@ -0,0 +1,46 @@ + + + + + + + + + + + +
Your supportFile is missing or invalid: /path/to/supportFile
+
+The supportFile must be a .js, .ts, .coffee file or be supported by your preprocessor plugin (if configured).
+
+Fix your support file, or set supportFile to false if a support file is not necessary for your project.
+
+If you have just renamed the extension of your supportFile, restart Cypress.
+
+https://on.cypress.io/support-file-missing-or-invalid
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/TESTS_DID_NOT_START_FAILED.html b/packages/errors/__snapshot-html__/TESTS_DID_NOT_START_FAILED.html new file mode 100644 index 000000000000..a1e6589e5562 --- /dev/null +++ b/packages/errors/__snapshot-html__/TESTS_DID_NOT_START_FAILED.html @@ -0,0 +1,38 @@ + + + + + + + + + + + +
The browser never connected. Something is wrong. The tests cannot run. Aborting...
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/TESTS_DID_NOT_START_RETRYING - retryingAgain.html b/packages/errors/__snapshot-html__/TESTS_DID_NOT_START_RETRYING - retryingAgain.html new file mode 100644 index 000000000000..8b0610392d57 --- /dev/null +++ b/packages/errors/__snapshot-html__/TESTS_DID_NOT_START_RETRYING - retryingAgain.html @@ -0,0 +1,38 @@ + + + + + + + + + + + +
Timed out waiting for the browser to connect. Retrying again...
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/TESTS_DID_NOT_START_RETRYING.html b/packages/errors/__snapshot-html__/TESTS_DID_NOT_START_RETRYING.html new file mode 100644 index 000000000000..87a1d43abd73 --- /dev/null +++ b/packages/errors/__snapshot-html__/TESTS_DID_NOT_START_RETRYING.html @@ -0,0 +1,38 @@ + + + + + + + + + + + +
Timed out waiting for the browser to connect. Retrying...
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/UNEXPECTED_BEFORE_BROWSER_LAUNCH_PROPERTIES.html b/packages/errors/__snapshot-html__/UNEXPECTED_BEFORE_BROWSER_LAUNCH_PROPERTIES.html new file mode 100644 index 000000000000..9d870a82c6e7 --- /dev/null +++ b/packages/errors/__snapshot-html__/UNEXPECTED_BEFORE_BROWSER_LAUNCH_PROPERTIES.html @@ -0,0 +1,48 @@ + + + + + + + + + + + +
The launchOptions object returned by your plugin's before:browser:launch handler contained unexpected properties:
+
+ - baz
+
+launchOptions may only contain the properties:
+
+ - preferences
+ - extensions
+ - args
+
+https://on.cypress.io/browser-launch-api
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/UNSUPPORTED_BROWSER_VERSION.html b/packages/errors/__snapshot-html__/UNSUPPORTED_BROWSER_VERSION.html new file mode 100644 index 000000000000..fd88bc7d472c --- /dev/null +++ b/packages/errors/__snapshot-html__/UNSUPPORTED_BROWSER_VERSION.html @@ -0,0 +1,38 @@ + + + + + + + + + + + +
Cypress does not support running chrome version 64. To use chrome with Cypress, install a version of chrome newer than or equal to 64.
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/VIDEO_POST_PROCESSING_FAILED.html b/packages/errors/__snapshot-html__/VIDEO_POST_PROCESSING_FAILED.html new file mode 100644 index 000000000000..d825c4409dc5 --- /dev/null +++ b/packages/errors/__snapshot-html__/VIDEO_POST_PROCESSING_FAILED.html @@ -0,0 +1,44 @@ + + + + + + + + + + + +
Warning: We failed processing this video.
+
+This error will not alter the exit code.
+
+Error: fail whale
+    at makeErr (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)
+    at VIDEO_POST_PROCESSING_FAILED (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)
+
\ No newline at end of file diff --git a/packages/errors/__snapshot-html__/VIDEO_RECORDING_FAILED.html b/packages/errors/__snapshot-html__/VIDEO_RECORDING_FAILED.html new file mode 100644 index 000000000000..b227d04f3322 --- /dev/null +++ b/packages/errors/__snapshot-html__/VIDEO_RECORDING_FAILED.html @@ -0,0 +1,44 @@ + + + + + + + + + + + +
Warning: We failed to record the video.
+
+This error will not alter the exit code.
+
+Error: fail whale
+    at makeErr (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)
+    at VIDEO_RECORDING_FAILED (cypress/packages/errors/test/unit/visualSnapshotErrors_spec.ts)
+
\ No newline at end of file diff --git a/packages/server/__snapshots__/errors_spec.js b/packages/errors/__snapshots__/errors_spec.ts.js similarity index 100% rename from packages/server/__snapshots__/errors_spec.js rename to packages/errors/__snapshots__/errors_spec.ts.js diff --git a/packages/errors/index.js b/packages/errors/index.js new file mode 100644 index 000000000000..a2958b789f92 --- /dev/null +++ b/packages/errors/index.js @@ -0,0 +1 @@ +module.exports = require('./src') diff --git a/packages/errors/package.json b/packages/errors/package.json new file mode 100644 index 000000000000..38d492e2ccce --- /dev/null +++ b/packages/errors/package.json @@ -0,0 +1,46 @@ +{ + "name": "@packages/errors", + "version": "0.0.0-development", + "description": "Error definitions and utilities for Cypress", + "main": "index.js", + "browser": "src/index.ts", + "scripts": { + "test": "yarn test-unit", + "comparison": "node -r @packages/ts/register test/support/error-comparison-tool.ts", + "build": "../../scripts/run-if-ci.sh tsc || echo 'type errors'", + "build-prod": "tsc", + "check-ts": "tsc --noEmit", + "clean-deps": "rm -rf node_modules", + "clean": "rm -f ./src/*.js ./src/**/*.js ./src/**/**/*.js ./test/**/*.js || echo 'cleaned'", + "pretest-unit": "yarn clean", + "test-unit": "mocha", + "test-electron": "HTML_IMAGE_CONVERSION=1 xvfb-maybe electron --no-sandbox ./node_modules/.bin/_mocha" + }, + "dependencies": { + "ansi_up": "5.0.0", + "strip-ansi": "6.0.0" + }, + "devDependencies": { + "@packages/ts": "0.0.0-development", + "@types/chai": "4.2.15", + "@types/mocha": "8.2.2", + "@types/node": "14.14.31", + "@types/pixelmatch": "^5.2.4", + "@types/pngjs": "^6.0.1", + "@types/strip-ansi": "^5.2.1", + "ansi-styles": "^5", + "chai": "4.2.0", + "globby": "^11.1.0", + "is-ci": "^3.0.1", + "mocha": "7.0.1", + "pngjs": "^6.0.0", + "sinon": "7.5.0", + "terminal-banner": "^1.1.0", + "xvfb-maybe": "^0.2.1" + }, + "files": [ + "src", + "dist" + ], + "types": "src/index.ts" +} diff --git a/packages/errors/src/errTemplate.ts b/packages/errors/src/errTemplate.ts new file mode 100644 index 000000000000..30931a6bb8c1 --- /dev/null +++ b/packages/errors/src/errTemplate.ts @@ -0,0 +1,344 @@ +import assert from 'assert' +import chalk from 'chalk' +import _ from 'lodash' +import stripAnsi from 'strip-ansi' +import { trimMultipleNewLines } from './errorUtils' +import { stripIndent } from './stripIndent' + +import type { ErrTemplateResult, SerializedError } from './errorTypes' + +interface ListOptions { + prefix?: string + color?: keyof typeof theme +} + +export const theme = { + blue: chalk.blueBright, + gray: chalk.gray, + white: chalk.white, + yellow: chalk.yellow, + magenta: chalk.magentaBright, +} + +type AllowedPartialArg = Guard | Format | PartialErr | null + +type AllowedTemplateArg = StackTrace | AllowedPartialArg + +export class PartialErr { + constructor (readonly strArr: TemplateStringsArray, readonly args: AllowedTemplateArg[]) {} +} + +interface FormatConfig { + block?: true + color?: typeof theme[keyof typeof theme] + stringify?: boolean +} + +type ToFormat = string | number | Error | object | null | Guard | AllowedTemplateArg + +class Format { + constructor ( + readonly type: keyof typeof fmtHighlight, + readonly val: ToFormat, + readonly config: FormatConfig, + ) { + this.color = config.color || fmtHighlight[this.type] + } + + private color: typeof theme[keyof typeof theme] + + formatVal (target: 'ansi' | 'markdown'): string { + if (this.val instanceof Guard) { + return `${this.val.val}` + } + + const str = target === 'ansi' ? this.formatAnsi() : this.formatMarkdown() + + // add a newline to ensure this is on its own line + return isMultiLine(str) ? `\n\n${str}` : str + } + + private formatAnsi () { + const val = this.prepVal('ansi') + + if (this.type === 'terminal') { + return `${theme.gray('$')} ${this.color(val)}` + } + + return this.color(val) + } + + private formatMarkdown () { + if (this.type === 'comment') { + return `${this.val}` + } + + const val = this.prepVal('markdown') + + if (this.type === 'terminal') { + return `${'```'}\n$ ${val}\n${'```'}` + } + + if (this.type === 'code') { + return `${'```'}\n${val}\n${'```'}` + } + + return mdFence(this.prepVal('markdown')) + } + + private prepVal (target: 'ansi' | 'markdown'): string { + if (this.val instanceof PartialErr) { + return prepMessage(this.val.strArr, this.val.args, target, true) + } + + if (isErrorLike(this.val)) { + return `${this.val.name}: ${this.val.message}` + } + + if (this.val && (this.config?.stringify || typeof this.val === 'object' || Array.isArray(this.val))) { + return JSON.stringify(this.val, null, 2) + } + + return `${this.val}` + } +} + +function mdFence (val: string) { + // Don't double fence values + if (val.includes('`')) { + return val + } + + if (isMultiLine(val)) { + return `\`\`\`\n${val}\n\`\`\`` + } + + return `\`${val}\`` +} + +function isMultiLine (val: string) { + return Boolean(val.split('\n').length > 1) +} + +function makeFormat (type: keyof typeof fmtHighlight, config?: FormatConfig) { + return (val: ToFormat, overrides?: FormatConfig) => { + return new Format(type, val, { + ...config, + ...overrides, + }) + } +} + +const fmtHighlight = { + meta: theme.gray, + comment: theme.gray, + path: theme.blue, + code: theme.blue, + url: theme.blue, + flag: theme.magenta, + stringify: theme.magenta, + highlight: theme.yellow, + highlightSecondary: theme.magenta, + highlightTertiary: theme.blue, + terminal: theme.blue, +} as const + +export const fmt = { + meta: makeFormat('meta'), + comment: makeFormat('comment'), + path: makeFormat('path'), + code: makeFormat('code', { block: true }), + url: makeFormat('url'), + flag: makeFormat('flag'), + stringify: makeFormat('stringify', { stringify: true }), + highlight: makeFormat('highlight'), + highlightSecondary: makeFormat('highlightSecondary'), + highlightTertiary: makeFormat('highlightTertiary'), + terminal: makeFormat('terminal'), + off: guard, + listItem, + listItems, + listFlags, + stackTrace, + cypressVersion, +} + +function cypressVersion (version: string) { + const parts = version.split('.') + + if (parts.length !== 3) { + throw new Error('Cypress version provided must be in x.x.x format') + } + + return guard(`Cypress version ${version}`) +} + +function _item (item: string, options: ListOptions = {}) { + const { prefix, color } = _.defaults(options, { + prefix: '', + color: 'blue', + }) + + return stripIndent`${theme.gray(prefix)}${theme[color](item)}` +} + +function listItem (item: string, options: ListOptions = {}) { + _.defaults(options, { + prefix: ' > ', + }) + + return guard(_item(item, options)) +} + +function listItems (items: string[], options: ListOptions = {}) { + _.defaults(options, { + prefix: ' - ', + }) + + return guard(items + .map((item) => _item(item, options)) + .join('\n')) +} + +function listFlags ( + obj: Record, + mapper: Record, +) { + return guard(_ + .chain(mapper) + .map((flag, key) => { + const v = obj[key] + + if (v) { + return `The ${flag} flag you passed was: ${theme.yellow(v)}` + } + + return undefined + }) + .compact() + .join('\n') + .value()) +} + +export class Guard { + constructor (readonly val: string | number) {} +} + +/** + * Prevents a string from being colored "blue" when wrapped in the errTemplate + * tag template literal + */ +export function guard (val: string | number) { + return new Guard(val) +} + +/** + * Marks the value as "details". This is when we print out the stack trace to the console + * (if it's an error), or use the stack trace as the originalError + */ +export class StackTrace { + /** + * @param {string | Error | object} stackTrace + */ + constructor (readonly val: string | Error | object) {} +} + +export function stackTrace (val: string | Error | object) { + return new StackTrace(val) +} + +export function isErrorLike (err: any): err is SerializedError | Error { + return err && typeof err === 'object' && Boolean('name' in err && 'message' in err) +} + +/** + * Creates a "partial" that can be interpolated into the full Error template. The partial runs through + * stripIndent prior to being added into the template + */ +export const errPartial = (templateStr: TemplateStringsArray, ...args: AllowedPartialArg[]) => { + return new PartialErr(templateStr, args) +} + +let originalError: Error | undefined = undefined +let details: string | undefined + +/** + * Creates a consistently formatted object to return from the error call. + * + * For the console: + * - By default, wrap every arg in yellow, unless it's "guarded" or is a "details" + * - Details stack gets logged at the end of the message in gray | magenta + * + * For the browser: + * - Wrap every arg in backticks, for better rendering in markdown + * - If details is an error, it gets provided as originalError + */ +export const errTemplate = (strings: TemplateStringsArray, ...args: AllowedTemplateArg[]): ErrTemplateResult => { + const msg = trimMultipleNewLines(prepMessage(strings, args, 'ansi')) + + return { + message: msg, + details, + originalError, + messageMarkdown: trimMultipleNewLines(stripAnsi(prepMessage(strings, args, 'markdown'))), + } +} + +/** + * Takes an `errTemplate` / `errPartial` and converts it into a string, formatted conditionally + * depending on the target environment + * + * @param templateStrings + * @param args + * @param target + * @returns + */ +function prepMessage (templateStrings: TemplateStringsArray, args: AllowedTemplateArg[], target: 'ansi' | 'markdown', isPartial: boolean = false): string { + // Reset the originalError to undefined on each new template string pass, we only need it to guard + if (!isPartial) { + originalError = undefined + details = undefined + } + + const templateArgs: string[] = [] + + for (const arg of args) { + // We assume null/undefined values are skipped when rendering, for conditional templating + if (arg == null) { + templateArgs.push('') + } else if (arg instanceof Guard) { + // Guard prevents any formatting + templateArgs.push(`${arg.val}`) + } else if (arg instanceof Format) { + // Format = stringify & color ANSI, or make a markdown block + templateArgs.push(arg.formatVal(target)) + } else if (arg instanceof StackTrace) { + assert(!originalError, `Cannot use fmt.stackTrace() multiple times in the same errTemplate`) + assert(!isPartial, `Cannot use fmt.stackTrace() in errPartial template string`) + + if (isErrorLike(arg.val)) { + originalError = arg.val + details = originalError.stack + } else { + if (process.env.CYPRESS_INTERNAL_ENV !== 'production') { + throw new Error(`Cannot use arg.stackTrace with a non error-like value, saw ${JSON.stringify(arg.val)}`) + } + + const err = new Error() + + err.stack = typeof arg.val === 'string' ? arg.val : JSON.stringify(arg.val) + originalError = err + details = err.stack + } + + templateArgs.push('') + } else if (arg instanceof PartialErr) { + // Partial error = prepMessage + interpolate + templateArgs.push(prepMessage(arg.strArr, arg.args, target, true)) + } else { + throw new Error(`Invalid value passed to prepMessage, saw ${arg}`) + } + } + + return stripIndent(templateStrings, ...templateArgs) +} diff --git a/packages/errors/src/errorTypes.ts b/packages/errors/src/errorTypes.ts new file mode 100644 index 000000000000..8e2fcda155aa --- /dev/null +++ b/packages/errors/src/errorTypes.ts @@ -0,0 +1,68 @@ +import type { AllCypressErrors } from './errors' + +/** + * A config validation result +*/ +export interface ConfigValidationError { + key: string + type: string + value: any + list?: string +} + +/** + * An "error like" is an object which may or may-not be an error, + * but contains at least a name & message, and probably a stack + */ +export interface ErrorLike { + name: string + message: string + stack?: string + // An error-like can have additional properties + [key: string]: any +} + +/** + * An error originating from the @cypress/errors package, + * includes the `type` of the error, the `originalError` + * if one exists, and an isCypressError for duck-type checking + */ +export interface CypressError extends ErrorLike { + messageMarkdown: string + type: keyof typeof AllCypressErrors + isCypressErr: boolean + originalError?: CypressError | ErrorLike + details?: string + code?: string | number + errno?: string | number + stackWithoutMessage?: string +} + +export interface ErrTemplateResult { + message: string + messageMarkdown: string + details?: string + originalError?: Error +} + +export interface ClonedError { + type: string + name: string + columnNumber?: string + lineNumber?: string + fileName?: String + stack?: string + message?: string + [key: string]: any +} + +export interface SerializedError { + code?: string | number + type?: string | number + errorType?: string + stack?: string + annotated?: string + message: string + name: string + isCypressErr?: boolean +} diff --git a/packages/errors/src/errorUtils.ts b/packages/errors/src/errorUtils.ts new file mode 100644 index 000000000000..501249803ee7 --- /dev/null +++ b/packages/errors/src/errorUtils.ts @@ -0,0 +1,71 @@ +/* eslint-disable no-console */ +import chalk from 'chalk' +import _ from 'lodash' +import path from 'path' + +const pluralize = require('pluralize') +const humanTime = require('@packages/server/lib/util/human_time') + +import type { CypressError, ErrorLike } from './errorTypes' + +export { + pluralize, + humanTime, +} + +const whileMatching = (othArr: string[]) => { + return (val: string, index: number) => { + return val === othArr[index] + } +} + +export const parseResolvedPattern = (baseFolder: string, globPattern: string) => { + const resolvedPath = path.resolve(baseFolder, globPattern) + const resolvedPathParts = resolvedPath.split(path.sep) + const folderPathPaths = baseFolder.split(path.sep) + const commonPath = _.takeWhile(folderPathPaths, whileMatching(resolvedPathParts)).join(path.sep) + const remainingPattern = !commonPath ? resolvedPath : resolvedPath.replace(commonPath.concat(path.sep), '') + + return [commonPath, remainingPattern] +} + +export const isCypressErr = (err: ErrorLike): err is CypressError => { + return Boolean(err.isCypressErr) +} + +const twoOrMoreNewLinesRe = /\n{2,}/ + +export const trimMultipleNewLines = (str: string) => { + return _ + .chain(str) + .split(twoOrMoreNewLinesRe) + .compact() + .join('\n\n') + .value() +} + +type AllowedChalkColors = 'red' | 'blue' | 'green' | 'magenta' | 'yellow' + +/** + * + * @param err + * @param color + * @returns + */ +export const logError = function (err: CypressError | ErrorLike, color: AllowedChalkColors = 'red') { + console.log(chalk[color](err.message)) + + if (err.details) { + console.log(chalk.magenta(`\n${err.details}`)) + } + + // bail if this error came from known + // list of Cypress errors + if (isCypressErr(err)) { + return + } + + console.log(chalk[color](err.stack ?? '')) + + return err +} diff --git a/packages/errors/src/errors.ts b/packages/errors/src/errors.ts new file mode 100644 index 000000000000..34b609463565 --- /dev/null +++ b/packages/errors/src/errors.ts @@ -0,0 +1,1414 @@ +import AU from 'ansi_up' +/* eslint-disable no-console */ +import chalk from 'chalk' +import _ from 'lodash' +import path from 'path' +import stripAnsi from 'strip-ansi' +import type { BreakingErrResult, TestingType } from '@packages/types' + +import { humanTime, logError, parseResolvedPattern, pluralize } from './errorUtils' +import { errPartial, errTemplate, fmt, theme, PartialErr } from './errTemplate' +import { stackWithoutMessage } from './stackUtils' + +import type { ClonedError, ConfigValidationError, CypressError, ErrTemplateResult, ErrorLike } from './errorTypes' + +const ansi_up = new AU() + +ansi_up.use_classes = true + +const displayRetriesRemaining = function (tries: number) { + const times = tries === 1 ? 'time' : 'times' + + const lastTryNewLine = tries === 1 ? '\n' : '' + + return fmt.meta( + `We will try connecting to it ${tries} more ${times}...${lastTryNewLine}`, + ) +} + +const getUsedTestsMessage = (limit: number, usedTestsMessage: string) => { + return _.isFinite(limit) + ? fmt.off(`The limit is ${chalk.yellow(`${limit}`)} ${usedTestsMessage} results.`) + : fmt.off('') +} + +export const warnIfExplicitCiBuildId = function (ciBuildId?: string | null) { + if (!ciBuildId) { + return null + } + + return errPartial`\ +It also looks like you also passed in an explicit ${fmt.flag('--ci-build-id')} flag. + +This is only necessary if you are NOT running in one of our supported CI providers. + +This flag must be unique for each new run, but must also be identical for each machine you are trying to --group or run in --parallel.\ +` +} + +/** + * All Cypress Errors should be defined here: + * + * The errors must return an "errTemplate", this is processed by the + */ +export const AllCypressErrors = { + CANNOT_TRASH_ASSETS: (arg1: Error) => { + return errTemplate`\ + Warning: We failed to trash the existing run results. + + This error will not alter the exit code. + + ${fmt.stackTrace(arg1)}` + }, + CANNOT_REMOVE_OLD_BROWSER_PROFILES: (arg1: Error) => { + return errTemplate`\ + Warning: We failed to remove old browser profiles from previous runs. + + This error will not alter the exit code. + + ${fmt.stackTrace(arg1)}` + }, + VIDEO_RECORDING_FAILED: (arg1: Error) => { + return errTemplate`\ + Warning: We failed to record the video. + + This error will not alter the exit code. + + ${fmt.stackTrace(arg1)}` + }, + VIDEO_POST_PROCESSING_FAILED: (arg1: Error) => { + return errTemplate`\ + Warning: We failed processing this video. + + This error will not alter the exit code. + + ${fmt.stackTrace(arg1)}` + }, + CHROME_WEB_SECURITY_NOT_SUPPORTED: (browser: string) => { + return errTemplate`\ + Your project has set the configuration option: ${fmt.highlight(`chromeWebSecurity`)} to ${fmt.highlightTertiary(`false`)} + + This option will not have an effect in ${fmt.off(_.capitalize(browser))}. Tests that rely on web security being disabled will not run as expected.` + }, + BROWSER_NOT_FOUND_BY_NAME: (browser: string, foundBrowsersStr: string[]) => { + let canarySuffix: PartialErr | null = null + + if (browser === 'canary') { + canarySuffix = errPartial`\ + ${fmt.off('\n\n')} + Note: In ${fmt.cypressVersion(`4.0.0`)}, Canary must be launched as ${fmt.highlightSecondary(`chrome:canary`)}, not ${fmt.highlightSecondary(`canary`)}. + + See https://on.cypress.io/migration-guide for more information on breaking changes in 4.0.0.` + } + + return errTemplate`\ + Can't run because you've entered an invalid browser name. + + Browser: ${fmt.highlight(browser)} was not found on your system or is not supported by Cypress. + + Cypress supports the following browsers: + ${fmt.listItems(['electron', 'chrome', 'chromium', 'chrome:canary', 'edge', 'firefox'])} + + You can also use a custom browser: https://on.cypress.io/customize-browsers + + Available browsers found on your system are: + ${fmt.listItems(foundBrowsersStr)}${canarySuffix}` + }, + BROWSER_NOT_FOUND_BY_PATH: (arg1: string, arg2: string) => { + return errTemplate`\ + We could not identify a known browser at the path you provided: ${fmt.path(arg1)} + + Read more about how to troubleshoot launching browsers: https://on.cypress.io/troubleshooting-launching-browsers + + The output from the command we ran was: + + ${fmt.highlightSecondary(arg2)}` + }, + NOT_LOGGED_IN: () => { + return errTemplate`\ + You're not logged in. + + Run ${fmt.highlight(`cypress open`)} to open the Desktop App and log in.` + }, + TESTS_DID_NOT_START_RETRYING: (arg1: string) => { + return errTemplate`Timed out waiting for the browser to connect. ${fmt.off(arg1)}` + }, + TESTS_DID_NOT_START_FAILED: () => { + return errTemplate`The browser never connected. Something is wrong. The tests cannot run. Aborting...` + }, + DASHBOARD_CANCEL_SKIPPED_SPEC: () => { + return errTemplate`${fmt.off(`\n `)}This spec and its tests were skipped because the run has been canceled.` + }, + DASHBOARD_API_RESPONSE_FAILED_RETRYING: (arg1: {tries: number, delay: number, response: Error}) => { + const time = pluralize('time', arg1.tries) + const delay = humanTime.long(arg1.delay, false) + + return errTemplate`\ + We encountered an unexpected error talking to our servers. + + We will retry ${fmt.off(arg1.tries)} more ${fmt.off(time)} in ${fmt.off(delay)}... + + The server's response was: + + ${fmt.highlightSecondary(arg1.response)}` + /* Because of fmt.listFlags() and fmt.listItems() */ + /* eslint-disable indent */ + }, + DASHBOARD_CANNOT_PROCEED_IN_PARALLEL: (arg1: {flags: any, response: Error}) => { + return errTemplate`\ + We encountered an unexpected error talking to our servers. + + Because you passed the ${fmt.flag(`--parallel`)} flag, this run cannot proceed because it requires a valid response from our servers. + + ${fmt.listFlags(arg1.flags, { + group: '--group', + ciBuildId: '--ciBuildId', + })} + + The server's response was: + + ${fmt.highlightSecondary(arg1.response)}` + }, + DASHBOARD_CANNOT_PROCEED_IN_SERIAL: (arg1: {flags: any, response: Error}) => { + return errTemplate`\ + We encountered an unexpected error talking to our servers. + + ${fmt.listFlags(arg1.flags, { + group: '--group', + ciBuildId: '--ciBuildId', + })} + + The server's response was: + + ${fmt.highlightSecondary(arg1.response)}` + }, + DASHBOARD_UNKNOWN_INVALID_REQUEST: (arg1: {flags: any, response: Error}) => { + return errTemplate`\ + We encountered an unexpected error talking to our servers. + + There is likely something wrong with the request. + + ${fmt.listFlags(arg1.flags, { + tags: '--tag', + group: '--group', + parallel: '--parallel', + ciBuildId: '--ciBuildId', + })} + + The server's response was: + + ${fmt.highlightSecondary(arg1.response)}` + }, + DASHBOARD_UNKNOWN_CREATE_RUN_WARNING: (arg1: {props: any, message: string}) => { + return errTemplate`\ + Warning from Cypress Dashboard: ${fmt.highlight(arg1.message)} + + Details: + ${fmt.meta(arg1.props)}` + }, + DASHBOARD_STALE_RUN: (arg1: {runUrl: string, [key: string]: any}) => { + return errTemplate`\ + You are attempting to pass the ${fmt.flag(`--parallel`)} flag to a run that was completed over 24 hours ago. + + The existing run is: ${fmt.url(arg1.runUrl)} + + You cannot parallelize a run that has been complete for that long. + + ${fmt.listFlags(arg1, { + tags: '--tag', + group: '--group', + parallel: '--parallel', + ciBuildId: '--ciBuildId', + })} + + https://on.cypress.io/stale-run` + }, + DASHBOARD_ALREADY_COMPLETE: (props: {runUrl: string}) => { + return errTemplate`\ + The run you are attempting to access is already complete and will not accept new groups. + + The existing run is: ${fmt.url(props.runUrl)} + + When a run finishes all of its groups, it waits for a configurable set of time before finally completing. You must add more groups during that time period. + + ${fmt.listFlags(props, { + tags: '--tag', + group: '--group', + parallel: '--parallel', + ciBuildId: '--ciBuildId', + })} + + https://on.cypress.io/already-complete` + }, + DASHBOARD_PARALLEL_REQUIRED: (arg1: {runUrl: string}) => { + return errTemplate`\ + You did not pass the ${fmt.flag(`--parallel`)} flag, but this run's group was originally created with the --parallel flag. + + The existing run is: ${fmt.url(arg1.runUrl)} + + ${fmt.listFlags(arg1, { + tags: '--tag', + group: '--group', + parallel: '--parallel', + ciBuildId: '--ciBuildId', + })} + + You must use the --parallel flag with this group. + + https://on.cypress.io/parallel-required` + }, + DASHBOARD_PARALLEL_DISALLOWED: (arg1: {runUrl: string}) => { + return errTemplate`\ + You passed the ${fmt.flag(`--parallel`)} flag, but this run group was originally created without the --parallel flag. + + The existing run is: ${fmt.url(arg1.runUrl)} + + ${fmt.listFlags(arg1, { + group: '--group', + parallel: '--parallel', + ciBuildId: '--ciBuildId', + })} + + You can not use the --parallel flag with this group. + + https://on.cypress.io/parallel-disallowed` + }, + DASHBOARD_PARALLEL_GROUP_PARAMS_MISMATCH: (arg1: {runUrl: string, parameters: any}) => { + return errTemplate`\ + You passed the ${fmt.flag(`--parallel`)} flag, but we do not parallelize tests across different environments. + + This machine is sending different environment parameters than the first machine that started this parallel run. + + The existing run is: ${fmt.url(arg1.runUrl)} + + In order to run in parallel mode each machine must send identical environment parameters such as: + + ${fmt.listItems([ + 'specs', + 'osName', + 'osVersion', + 'browserName', + 'browserVersion (major)', + ])} + + This machine sent the following parameters: + + ${fmt.meta(arg1.parameters)} + + https://on.cypress.io/parallel-group-params-mismatch` + }, + DASHBOARD_RUN_GROUP_NAME_NOT_UNIQUE: (arg1: {runUrl: string, ciBuildId?: string | null}) => { + return errTemplate`\ + You passed the ${fmt.flag(`--group`)} flag, but this group name has already been used for this run. + + The existing run is: ${fmt.url(arg1.runUrl)} + + ${fmt.listFlags(arg1, { + group: '--group', + parallel: '--parallel', + ciBuildId: '--ciBuildId', + })} + + If you are trying to parallelize this run, then also pass the ${fmt.flag(`--parallel`)} flag, else pass a different group name. + + ${warnIfExplicitCiBuildId(arg1.ciBuildId)} + + https://on.cypress.io/run-group-name-not-unique` + }, + DEPRECATED_BEFORE_BROWSER_LAUNCH_ARGS: () => { + return errTemplate`\ + Deprecation Warning: The ${fmt.highlight(`before:browser:launch`)} plugin event changed its signature in ${fmt.cypressVersion(`4.0.0`)} + + The event switched from yielding the second argument as an ${fmt.highlightSecondary(`array`)} of browser arguments to an options ${fmt.highlightSecondary(`object`)} with an ${fmt.highlightSecondary(`args`)} property. + + We've detected that your code is still using the previous, deprecated interface signature. + + This code will not work in a future version of Cypress. Please see the upgrade guide: https://on.cypress.io/deprecated-before-browser-launch-args` + }, + DUPLICATE_TASK_KEY: (arg1: string[]) => { + return errTemplate`\ + Warning: Multiple attempts to register the following task(s): + + ${fmt.listItems(arg1, { color: 'yellow' })} + + Only the last attempt will be registered.` + }, + INDETERMINATE_CI_BUILD_ID: (arg1: Record, arg2: string[]) => { + return errTemplate`\ + You passed the ${fmt.flag(`--group`)} or ${fmt.flag(`--parallel`)} flag but we could not automatically determine or generate a ciBuildId. + + ${fmt.listFlags(arg1, { + group: '--group', + parallel: '--parallel', + })} + + In order to use either of these features a ciBuildId must be determined. + + The ciBuildId is automatically detected if you are running Cypress in any of the these CI providers: + + ${fmt.listItems(arg2)} + + Because the ciBuildId could not be auto-detected you must pass the --ci-build-id flag manually. + + https://on.cypress.io/indeterminate-ci-build-id` + }, + RECORD_PARAMS_WITHOUT_RECORDING: (arg1: Record) => { + return errTemplate`\ + You passed the ${fmt.flag(`--ci-build-id`)}, ${fmt.flag(`--group`)}, ${fmt.flag(`--tag`)}, or ${fmt.flag(`--parallel`)} flag without also passing the ${fmt.flag(`--record`)} flag. + + ${fmt.listFlags(arg1, { + ciBuildId: '--ci-build-id', + tags: '--tag', + group: '--group', + parallel: '--parallel', + })} + + These flags can only be used when recording to the Cypress Dashboard service. + + https://on.cypress.io/record-params-without-recording` + }, + INCORRECT_CI_BUILD_ID_USAGE: (arg1: Record) => { + return errTemplate`\ + You passed the ${fmt.flag(`--ci-build-id`)} flag but did not provide either a ${fmt.flag(`--group`)} or ${fmt.flag(`--parallel`)} flag. + + ${fmt.listFlags(arg1, { + ciBuildId: '--ci-build-id', + })} + + The --ci-build-id flag is used to either group or parallelize multiple runs together. + + https://on.cypress.io/incorrect-ci-build-id-usage` + /* eslint-enable indent */ + }, + RECORD_KEY_MISSING: () => { + return errTemplate`\ + You passed the ${fmt.flag(`--record`)} flag but did not provide us your Record Key. + + You can pass us your Record Key like this: + + ${fmt.terminal(`cypress run --record --key `)} + + You can also set the key as an environment variable with the name: ${fmt.highlightSecondary(`CYPRESS_RECORD_KEY`)} + + https://on.cypress.io/how-do-i-record-runs` + }, + // TODO: make this relative path, not absolute + CANNOT_RECORD_NO_PROJECT_ID: (configFilePath: string) => { + return errTemplate`\ + You passed the ${fmt.flag(`--record`)} flag but this project has not been setup to record. + + This project is missing the ${fmt.highlight(`projectId`)} inside of: ${fmt.path(configFilePath)} + + We cannot uniquely identify this project without this id. + + You need to setup this project to record. This will generate a unique projectId. + + Alternatively if you omit the ${fmt.flag(`--record`)} flag this project will run without recording. + + https://on.cypress.io/recording-project-runs` + }, + PROJECT_ID_AND_KEY_BUT_MISSING_RECORD_OPTION: (arg1: string) => { + return errTemplate`\ + This project has been configured to record runs on our Dashboard. + + It currently has the projectId: ${fmt.highlight(arg1)} + + You also provided your Record Key, but you did not pass the ${fmt.flag(`--record`)} flag. + + This run will not be recorded. + + If you meant to have this run recorded please additionally pass this flag: + + ${fmt.terminal('cypress run --record')} + + If you don't want to record these runs, you can silence this warning: + + ${fmt.terminal('cypress run --record false')} + + https://on.cypress.io/recording-project-runs` + }, + DASHBOARD_INVALID_RUN_REQUEST: (arg1: {message: string, errors: string[], object: object}) => { + return errTemplate`\ + Recording this run failed because the request was invalid. + + ${fmt.highlight(arg1.message)} + + Errors: + + ${fmt.meta(arg1.errors)} + + Request Sent: + + ${fmt.meta(arg1.object)}` + }, + RECORDING_FROM_FORK_PR: () => { + return errTemplate`\ + Warning: It looks like you are trying to record this run from a forked PR. + + The ${fmt.highlight(`Record Key`)} is missing. Your CI provider is likely not passing private environment variables to builds from forks. + + These results will not be recorded. + + This error will not alter the exit code.` + }, + DASHBOARD_CANNOT_UPLOAD_RESULTS: (apiErr: Error) => { + return errTemplate`\ + Warning: We encountered an error while uploading results from your run. + + These results will not be recorded. + + This error will not alter the exit code. + + ${fmt.highlightSecondary(apiErr)}` + }, + DASHBOARD_CANNOT_CREATE_RUN_OR_INSTANCE: (apiErr: Error) => { + return errTemplate`\ + Warning: We encountered an error talking to our servers. + + This run will not be recorded. + + This error will not alter the exit code. + + ${fmt.highlightSecondary(apiErr)}` + }, + DASHBOARD_RECORD_KEY_NOT_VALID: (recordKey: string, projectId: string) => { + return errTemplate`\ + Your Record Key ${fmt.highlight(recordKey)} is not valid with this projectId: ${fmt.highlightSecondary(projectId)} + + It may have been recently revoked by you or another user. + + Please log into the Dashboard to see the valid record keys. + + https://on.cypress.io/dashboard/projects/${fmt.off(projectId)}` + }, + DASHBOARD_PROJECT_NOT_FOUND: (projectId: string, configFileBaseName: string) => { + return errTemplate`\ + We could not find a Dashboard project with the projectId: ${fmt.highlight(projectId)} + + This ${fmt.highlightSecondary(`projectId`)} came from your ${fmt.path(configFileBaseName)} file or an environment variable. + + Please log into the Dashboard and find your project. + + We will list the correct projectId in the 'Settings' tab. + + Alternatively, you can create a new project using the Desktop Application. + + https://on.cypress.io/dashboard` + }, + // TODO: make this relative path, not absolute + NO_PROJECT_ID: (configFilePath: string | false) => { + return errTemplate`Can't find ${fmt.highlight(`projectId`)} in the config file: ${fmt.path(configFilePath || '')}` + }, + NO_PROJECT_FOUND_AT_PROJECT_ROOT: (projectRoot: string) => { + return errTemplate`Can't find a project at the path: ${fmt.path(projectRoot)}` + }, + CANNOT_FETCH_PROJECT_TOKEN: () => { + return errTemplate`Can't find project's secret key.` + }, + CANNOT_CREATE_PROJECT_TOKEN: () => { + return errTemplate`Can't create project's secret key.` + }, + PORT_IN_USE_SHORT: (arg1: string | number) => { + return errTemplate`Port ${fmt.highlight(arg1)} is already in use.` + }, + PORT_IN_USE_LONG: (arg1: string | number) => { + return errTemplate`\ + Can't run project because port is currently in use: ${fmt.highlight(arg1)} + + Assign a different port with the ${fmt.flag(`--port `)} argument or shut down the other running process.` + }, + ERROR_READING_FILE: (filePath: string, err: Error) => { + return errTemplate`\ + Error reading from: ${fmt.path(filePath)} + + ${fmt.stackTrace(err)}` + }, + ERROR_WRITING_FILE: (filePath: string, err: Error) => { + return errTemplate`\ + Error writing to: ${fmt.path(filePath)} + + ${fmt.stackTrace(err)}` + }, + NO_SPECS_FOUND: (folderPath: string, globPattern?: string[] | string | null) => { + // no glob provided, searched all specs + if (!globPattern) { + return errTemplate`\ + Can't run because ${fmt.highlightSecondary(`no spec files`)} were found. + + We searched for specs inside of this folder: + + ${fmt.listItem(folderPath)}` + } + + const globPaths = _.castArray(globPattern).map((pattern) => { + const [resolvedBasePath, resolvedPattern] = parseResolvedPattern(folderPath, pattern) + + return path.join(resolvedBasePath!, theme.yellow(resolvedPattern!)) + }) + + const phrase = globPaths.length > 1 ? 'these glob patterns' : 'this glob pattern' + + return errTemplate`\ + Can't run because ${fmt.highlightSecondary(`no spec files`)} were found. + + We searched for specs matching ${fmt.off(phrase)}: + + ${fmt.listItems(globPaths, { color: 'blue', prefix: ' > ' })}` + }, + RENDERER_CRASHED: () => { + return errTemplate`\ + We detected that the Chromium Renderer process just crashed. + + This is the equivalent to seeing the 'sad face' when Chrome dies. + + This can happen for a number of different reasons: + + - You wrote an endless loop and you must fix your own code + - There is a memory leak in Cypress (unlikely but possible) + - You are running Docker (there is an easy fix for this: see link below) + - You are running lots of tests on a memory intense application + - You are running in a memory starved VM environment + - There are problems with your GPU / GPU drivers + - There are browser bugs in Chromium + + You can learn more including how to fix Docker here: + + https://on.cypress.io/renderer-process-crashed` + }, + AUTOMATION_SERVER_DISCONNECTED: () => { + return errTemplate`The automation client disconnected. Cannot continue running tests.` + }, + // TODO: make this relative path, not absolute + SUPPORT_FILE_NOT_FOUND: (supportFilePath: string) => { + return errTemplate`\ + Your ${fmt.highlight(`supportFile`)} is missing or invalid: ${fmt.path(supportFilePath)} + + The supportFile must be a .js, .ts, .coffee file or be supported by your preprocessor plugin (if configured). + + Fix your support file, or set supportFile to ${fmt.highlightSecondary(`false`)} if a support file is not necessary for your project. + + If you have just renamed the extension of your supportFile, restart Cypress. + + https://on.cypress.io/support-file-missing-or-invalid` + }, + // TODO: make this relative path, not absolute + CONFIG_FILE_REQUIRE_ERROR: (configFilePath: string, err: Error) => { + return errTemplate`\ + Your ${fmt.highlight(`configFile`)} is invalid: ${fmt.path(configFilePath)} + + It threw an error when required, check the stack trace below: + + ${fmt.stackTrace(err)} + ` + }, + // TODO: make this relative path, not absolute + SETUP_NODE_EVENTS_IS_NOT_FUNCTION: (configFilePath: string, testingType: string, exported: any) => { + const code = errPartial` + { + ${fmt.off(testingType)}: { + setupNodeEvents(on, config) { + ${fmt.comment(`// configure tasks and plugins here`)} + } + } + }` + + return errTemplate`\ + Your ${fmt.highlight(`configFile`)} is invalid: ${fmt.path(configFilePath)} + + The ${fmt.highlightSecondary(`${testingType}.setupNodeEvents()`)} function must be defined with the following signature: + + ${fmt.code(code)} + + Instead we saw: + + ${fmt.stringify(exported)} + + https://on.cypress.io/plugins-api + ` + }, + CONFIG_FILE_SETUP_NODE_EVENTS_ERROR: (configFilePath: string, testingType: TestingType, err: ErrorLike) => { + return errTemplate` + Your ${fmt.highlightSecondary(`configFile`)} threw an error from: ${fmt.path(configFilePath)} + + The error was thrown while executing your ${fmt.highlight(`${testingType}.setupNodeEvents()`)} function: + + ${fmt.stackTrace(err)} + ` + }, + CONFIG_FILE_UNEXPECTED_ERROR: (configFilePath: string, err: ErrorLike) => { + return errTemplate` + Your ${fmt.highlight(`configFile`)} threw an error from: ${fmt.path(configFilePath)} + + We stopped running your tests because your config file crashed. + + ${fmt.stackTrace(err)} + ` + }, + // TODO: make this relative path, not absolute + PLUGINS_INVALID_EVENT_NAME_ERROR: (pluginsFilePath: string, invalidEventName: string, validEventNames: string[], err: Error) => { + return errTemplate` + Your ${fmt.highlightSecondary(`configFile`)} threw a validation error from: ${fmt.path(pluginsFilePath)} + + You must pass a valid event name when registering a plugin. + + You passed: ${fmt.highlight(invalidEventName)} + + The following are valid events: + + ${fmt.listItems(validEventNames)} + + ${fmt.stackTrace(err)} + ` + }, + BUNDLE_ERROR: (filePath: string, arg2: string) => { + // IF YOU MODIFY THIS MAKE SURE TO UPDATE + // THE ERROR MESSAGE IN THE RUNNER TOO + return errTemplate`\ + Oops...we found an error preparing this test file: + + ${fmt.listItem(filePath)} + + The error was: + + ${fmt.highlight(arg2)} + + This occurred while Cypress was compiling and bundling your test code. This is usually caused by: + + - A missing file or dependency + - A syntax error in the file or one of its dependencies + + Fix the error in your code and re-run your tests.` + }, + // happens when there is an error in configuration file like "cypress.json" + // TODO: make this relative path, not absolute + CONFIG_VALIDATION_MSG_ERROR: (fileType: 'configFile' | 'pluginsFile' | null, fileName: string | null, validationMsg: string) => { + if (!fileType) { + return errTemplate` + An invalid configuration value was set: + + ${fmt.highlight(validationMsg)}` + } + + return errTemplate` + Your ${fmt.highlight(fileType)} as ${fmt.path(fileName)} set an invalid value: + + ${fmt.highlight(validationMsg)}` + }, + // TODO: make this relative path, not absolute + CONFIG_VALIDATION_ERROR: (fileType: 'configFile' | 'pluginsFile' | null, filePath: string | null, validationResult: ConfigValidationError) => { + const { key, type, value, list } = validationResult + + if (!fileType) { + return errTemplate`\ + An invalid configuration value was set. + + Expected ${fmt.highlight(key)} to be ${fmt.off(type)}. + + Instead the value was: ${fmt.stringify(value)}` + } + + if (list) { + return errTemplate`\ + Your ${fmt.highlight(fileType)} at ${fmt.path(filePath)} set an invalid value: + + The error occurred while validating the ${fmt.highlightSecondary(list)} list. + + Expected ${fmt.highlight(key)} to be ${fmt.off(type)}. + + Instead the value was: ${fmt.stringify(value)}` + } + + return errTemplate`\ + Your ${fmt.highlight(fileType)} at ${fmt.path(filePath)} set an invalid value: + + Expected ${fmt.highlight(key)} to be ${fmt.off(type)}. + + Instead the value was: ${fmt.stringify(value)}` + }, + RENAMED_CONFIG_OPTION: (arg1: {name: string, newName: string}) => { + return errTemplate`\ + The ${fmt.highlight(arg1.name)} configuration option you have supplied has been renamed. + + Please rename ${fmt.highlight(arg1.name)} to ${fmt.highlightSecondary(arg1.newName)}` + }, + CANNOT_CONNECT_BASE_URL: () => { + return errTemplate`\ + Cypress failed to verify that your server is running. + + Please start this server and then run Cypress again.` + }, + CANNOT_CONNECT_BASE_URL_WARNING: (arg1: string) => { + return errTemplate`\ + Cypress could not verify that this server is running: + + ${fmt.listItem(arg1)} + + This server has been configured as your ${fmt.highlight(`baseUrl`)}, and tests will likely fail if it is not running.` + }, + // TODO: test this + CANNOT_CONNECT_BASE_URL_RETRYING: (arg1: {attempt: number, baseUrl: string, remaining: number, delay: number}) => { + switch (arg1.attempt) { + case 1: + return errTemplate`\ + Cypress could not verify that this server is running: + + ${fmt.listItem(arg1.baseUrl)} + + We are verifying this server because it has been configured as your ${fmt.highlight(`baseUrl`)}. + + Cypress automatically waits until your server is accessible before running tests. + + ${displayRetriesRemaining(arg1.remaining)}` + default: + return errTemplate`${displayRetriesRemaining(arg1.remaining)}` + } + }, + // TODO: test this + INVALID_REPORTER_NAME: (arg1: {name: string, paths: string[], error: Error}) => { + return errTemplate`\ + Error loading the reporter: ${fmt.highlight(arg1.name)} + + We searched for the reporter in these paths: + + ${fmt.listItems(arg1.paths)} + + Learn more at https://on.cypress.io/reporters + + ${fmt.stackTrace(arg1.error)} + ` + }, + // TODO: manually test this + NO_DEFAULT_CONFIG_FILE_FOUND: (arg1: string) => { + return errTemplate`\ + Could not find a Cypress configuration file in this folder: ${fmt.path(arg1)}` + }, + // TODO: verify these are configBaseName and not configPath + CONFIG_FILES_LANGUAGE_CONFLICT: (projectRoot: string, configFileBaseName1: string, configFileBaseName2: string) => { + return errTemplate` + There is both a ${fmt.highlight(configFileBaseName1)} and a ${fmt.highlight(configFileBaseName2)} at the location below: + + ${fmt.listItem(projectRoot)} + + Cypress does not know which one to read for config. Please remove one of the two and try again.` + }, + CONFIG_FILE_NOT_FOUND: (configFileBaseName: string, projectRoot: string) => { + return errTemplate`\ + Could not find a Cypress configuration file. + + We looked but did not find a ${fmt.highlight(configFileBaseName)} file in this folder: ${fmt.path(projectRoot)}` + }, + INVOKED_BINARY_OUTSIDE_NPM_MODULE: () => { + return errTemplate`\ + It looks like you are running the Cypress binary directly. + + This is not the recommended approach, and Cypress may not work correctly. + + Please install the ${fmt.highlight(`cypress`)} NPM package and follow the instructions here: + + https://on.cypress.io/installing-cypress` + }, + FREE_PLAN_EXCEEDS_MONTHLY_PRIVATE_TESTS: (arg1: {link: string, usedTestsMessage: string, limit: number}) => { + return errTemplate`\ + You've exceeded the limit of private test results under your free plan this month. ${getUsedTestsMessage(arg1.limit, arg1.usedTestsMessage)} + + To continue recording tests this month you must upgrade your account. Please visit your billing to upgrade to another billing plan. + + ${fmt.off(arg1.link)}` + }, + FREE_PLAN_IN_GRACE_PERIOD_EXCEEDS_MONTHLY_PRIVATE_TESTS: (arg1: {link: string, usedTestsMessage: string, gracePeriodMessage: string, limit: number}) => { + return errTemplate`\ + You've exceeded the limit of private test results under your free plan this month. ${getUsedTestsMessage(arg1.limit, arg1.usedTestsMessage)} + + Your plan is now in a grace period, which means your tests will still be recorded until ${fmt.off(arg1.gracePeriodMessage)}. Please upgrade your plan to continue recording tests on the Cypress Dashboard in the future. + + ${fmt.off(arg1.link)}` + }, + PAID_PLAN_EXCEEDS_MONTHLY_PRIVATE_TESTS: (arg1: {link: string, usedTestsMessage: string, limit: number}) => { + return errTemplate`\ + You've exceeded the limit of private test results under your current billing plan this month. ${getUsedTestsMessage(arg1.limit, arg1.usedTestsMessage)} + + To upgrade your account, please visit your billing to upgrade to another billing plan. + + ${fmt.off(arg1.link)}` + }, + FREE_PLAN_EXCEEDS_MONTHLY_TESTS: (arg1: {link: string, usedTestsMessage: string, limit: number}) => { + return errTemplate`\ + You've exceeded the limit of test results under your free plan this month. ${getUsedTestsMessage(arg1.limit, arg1.usedTestsMessage)} + + To continue recording tests this month you must upgrade your account. Please visit your billing to upgrade to another billing plan. + + ${fmt.off(arg1.link)}` + }, + FREE_PLAN_IN_GRACE_PERIOD_EXCEEDS_MONTHLY_TESTS: (arg1: {link: string, usedTestsMessage: string, gracePeriodMessage: string, limit: number}) => { + return errTemplate`\ + You've exceeded the limit of test results under your free plan this month. ${getUsedTestsMessage(arg1.limit, arg1.usedTestsMessage)} + + Your plan is now in a grace period, which means you will have the full benefits of your current plan until ${fmt.highlight(arg1.gracePeriodMessage)}. + + Please visit your billing to upgrade your plan. + + ${fmt.off(arg1.link)}` + }, + PLAN_EXCEEDS_MONTHLY_TESTS: (arg1: {link: string, planType: string, usedTestsMessage: string, limit: number}) => { + return errTemplate`\ + You've exceeded the limit of test results under your ${fmt.highlight(arg1.planType)} billing plan this month. ${getUsedTestsMessage(arg1.limit, arg1.usedTestsMessage)} + + To continue getting the full benefits of your current plan, please visit your billing to upgrade. + + ${fmt.off(arg1.link)}` + }, + FREE_PLAN_IN_GRACE_PERIOD_PARALLEL_FEATURE: (arg1: {link: string, gracePeriodMessage: string}) => { + return errTemplate`\ + ${fmt.highlightSecondary(`Parallelization`)} is not included under your free plan. + + Your plan is now in a grace period, which means your tests will still run in parallel until ${fmt.highlight(arg1.gracePeriodMessage)}. Please upgrade your plan to continue running your tests in parallel in the future. + + ${fmt.off(arg1.link)}` + }, + PARALLEL_FEATURE_NOT_AVAILABLE_IN_PLAN: (arg1: {link: string}) => { + return errTemplate`\ + ${fmt.highlightSecondary(`Parallelization`)} is not included under your current billing plan. + + To run your tests in parallel, please visit your billing and upgrade to another plan with parallelization. + + ${fmt.off(arg1.link)}` + }, + PLAN_IN_GRACE_PERIOD_RUN_GROUPING_FEATURE_USED: (arg1: {link: string, gracePeriodMessage: string}) => { + return errTemplate`\ + ${fmt.highlightSecondary(`Grouping`)} is not included under your free plan. + + Your plan is now in a grace period, which means your tests will still run with groups until ${fmt.highlight(arg1.gracePeriodMessage)}. Please upgrade your plan to continue running your tests with groups in the future. + + ${fmt.off(arg1.link)}` + }, + RUN_GROUPING_FEATURE_NOT_AVAILABLE_IN_PLAN: (arg1: {link: string}) => { + return errTemplate`\ + ${fmt.highlightSecondary(`Grouping`)} is not included under your current billing plan. + + To run your tests with groups, please visit your billing and upgrade to another plan with grouping. + + ${fmt.off(arg1.link)}` + }, + // TODO: fix + FIXTURE_NOT_FOUND: (arg1: string, arg2: string[]) => { + return errTemplate`\ + A fixture file could not be found at any of the following paths: + + ${fmt.listItem(arg1)} + ${fmt.listItem(arg1)}.[ext] + + Cypress looked for these file extensions at the provided path: + + ${fmt.listItem(arg2.join(', '))} + + Provide a path to an existing fixture file.` + }, + BAD_POLICY_WARNING: (policyKeys: string[]) => { + return errTemplate`\ + Cypress detected policy settings on your computer that may cause issues. + + The following policies were detected that may prevent Cypress from automating Chrome: + + ${fmt.listItems(policyKeys)} + + For more information, see https://on.cypress.io/bad-browser-policy` + }, + BAD_POLICY_WARNING_TOOLTIP: () => { + return errTemplate`Cypress detected policy settings on your computer that may cause issues with using this browser. For more information, see https://on.cypress.io/bad-browser-policy` + }, + EXTENSION_NOT_LOADED: (browserName: string, extensionPath: string) => { + return errTemplate`\ + ${fmt.off(browserName)} could not install the extension at path: ${fmt.path(extensionPath)} + + Please verify that this is the path to a valid, unpacked WebExtension.` + }, + COULD_NOT_FIND_SYSTEM_NODE: (nodeVersion: string) => { + return errTemplate`\ + ${fmt.highlight(`nodeVersion`)} is set to ${fmt.highlightTertiary(`system`)} but Cypress could not find a usable Node executable on your ${fmt.highlightSecondary(`PATH`)}. + + Make sure that your Node executable exists and can be run by the current user. + + Cypress will use the built-in Node version ${fmt.highlightSecondary(nodeVersion)} instead.` + }, + INVALID_CYPRESS_INTERNAL_ENV: (val: string) => { + return errTemplate`\ + We have detected an unknown or unsupported ${fmt.highlightSecondary(`CYPRESS_INTERNAL_ENV`)} value: ${fmt.highlight(val)} + + CYPRESS_INTERNAL_ENV is reserved for internal use and cannot be modified.` + }, + CDP_VERSION_TOO_OLD: (minimumVersion: string, currentVersion: {major: number, minor: string | number}) => { + const phrase = currentVersion.major !== 0 + ? fmt.highlight(`${currentVersion.major}.${currentVersion.minor}`) + : fmt.off('an older version') + + return errTemplate`A minimum CDP version of ${fmt.highlight(minimumVersion)} is required, but the current browser has ${phrase}.` + }, + CDP_COULD_NOT_CONNECT: (browserName: string, port: number, err: Error) => { + // we include a stack trace here because it may contain useful information + // to debug since this is an "uncontrolled" error even though it doesn't + // come from a user + return errTemplate`\ + Cypress failed to make a connection to the Chrome DevTools Protocol after retrying for 50 seconds. + + This usually indicates there was a problem opening the ${fmt.off(_.capitalize(browserName))} browser. + + The CDP port requested was ${fmt.highlight(port)}. + + ${fmt.stackTrace(err)}` + }, + FIREFOX_COULD_NOT_CONNECT: (arg1: Error) => { + // we include a stack trace here because it may contain useful information + // to debug since this is an "uncontrolled" error even though it doesn't + // come from a user + return errTemplate`\ + Cypress failed to make a connection to Firefox. + + This usually indicates there was a problem opening the Firefox browser. + + ${fmt.stackTrace(arg1)}` + }, + CDP_COULD_NOT_RECONNECT: (arg1: Error) => { + return errTemplate`\ + There was an error reconnecting to the Chrome DevTools protocol. Please restart the browser. + + ${fmt.stackTrace(arg1)}` + }, + CDP_RETRYING_CONNECTION: (attempt: string | number, browserName: string) => { + return errTemplate`Still waiting to connect to ${fmt.off(_.capitalize(browserName))}, retrying in 1 second ${fmt.meta(`(attempt ${attempt}/62)`)}` + }, + UNEXPECTED_BEFORE_BROWSER_LAUNCH_PROPERTIES: (arg1: string[], arg2: string[]) => { + return errTemplate`\ + The ${fmt.highlight('launchOptions')} object returned by your plugin's ${fmt.highlightSecondary(`before:browser:launch`)} handler contained unexpected properties: + + ${fmt.listItems(arg1)} + + launchOptions may only contain the properties: + + ${fmt.listItems(arg2)} + + https://on.cypress.io/browser-launch-api` + }, + // TODO: test this + COULD_NOT_PARSE_ARGUMENTS: (argName: string, argValue: string, errMsg: string) => { + return errTemplate`\ + Cypress encountered an error while parsing the argument: ${fmt.highlight(`--${argName}`)} + + You passed: ${fmt.highlightTertiary(argValue)} + + The error was: ${fmt.highlightSecondary(errMsg)}` + }, + FIREFOX_MARIONETTE_FAILURE: (origin: string, err: Error) => { + return errTemplate`\ + Cypress could not connect to Firefox. + + An unexpected error was received from Marionette: ${fmt.highlightSecondary(origin)} + + To avoid this error, ensure that there are no other instances of Firefox launched by Cypress running. + + ${fmt.stackTrace(err)}` + }, + FOLDER_NOT_WRITABLE: (arg1: string) => { + return errTemplate`\ + This folder is not writable: ${fmt.path(arg1)} + + Writing to this directory is required by Cypress in order to store screenshots and videos. + + Enable write permissions to this directory to ensure screenshots and videos are stored. + + If you don't require screenshots or videos to be stored you can safely ignore this warning.` + }, + EXPERIMENTAL_SAMESITE_REMOVED: () => { + return errTemplate`\ + The ${fmt.highlight(`experimentalGetCookiesSameSite`)} configuration option was removed in ${fmt.cypressVersion(`5.0.0`)}. + + Returning the ${fmt.highlightSecondary(`sameSite`)} property is now the default behavior of the ${fmt.highlightSecondary(`cy.cookie`)} commands. + + You can safely remove this option from your config.` + }, + // TODO: verify configFile is absolute path + // TODO: make this relative path, not absolute + EXPERIMENTAL_COMPONENT_TESTING_REMOVED: (arg1: {configFile: string}) => { + return errTemplate`\ + The ${fmt.highlight('experimentalComponentTesting')} configuration option was removed in ${fmt.cypressVersion(`7.0.0`)}. + + Please remove this flag from: ${fmt.path(arg1.configFile)} + + Component Testing is now a standalone command. You can now run your component tests with: + + ${fmt.terminal(`cypress open-ct`)} + + https://on.cypress.io/migration-guide` + }, + EXPERIMENTAL_SHADOW_DOM_REMOVED: () => { + return errTemplate`\ + The ${fmt.highlight(`experimentalShadowDomSupport`)} configuration option was removed in ${fmt.cypressVersion(`5.2.0`)}. It is no longer necessary when utilizing the ${fmt.highlightSecondary(`includeShadowDom`)} option. + + You can safely remove this option from your config.` + }, + EXPERIMENTAL_NETWORK_STUBBING_REMOVED: () => { + return errTemplate`\ + The ${fmt.highlight(`experimentalNetworkStubbing`)} configuration option was removed in ${fmt.cypressVersion(`6.0.0`)}. + + It is no longer necessary for using ${fmt.highlightSecondary(`cy.intercept()`)}. You can safely remove this option from your config.` + }, + EXPERIMENTAL_RUN_EVENTS_REMOVED: () => { + return errTemplate`\ + The ${fmt.highlight(`experimentalRunEvents`)} configuration option was removed in ${fmt.cypressVersion(`6.7.0`)}. It is no longer necessary when listening to run events in the plugins file. + + You can safely remove this option from your config.` + }, + FIREFOX_GC_INTERVAL_REMOVED: () => { + return errTemplate`\ + The ${fmt.highlight(`firefoxGcInterval`)} configuration option was removed in ${fmt.cypressVersion(`8.0.0`)}. It was introduced to work around a bug in Firefox 79 and below. + + Since Cypress no longer supports Firefox 85 and below in Cypress ${fmt.cypressVersion(`8.0.0`)}, this option was removed. + + You can safely remove this option from your config.` + }, + // TODO: make this relative path, not absolute + INCOMPATIBLE_PLUGIN_RETRIES: (arg1: string) => { + return errTemplate`\ + We've detected that the incompatible plugin ${fmt.highlight(`cypress-plugin-retries`)} is installed at: ${fmt.path(arg1)} + + Test retries is now natively supported in ${fmt.cypressVersion(`5.0.0`)}. + + Remove the plugin from your dependencies to silence this warning. + + https://on.cypress.io/test-retries + ` + }, + // TODO: test this + INVALID_CONFIG_OPTION: (arg1: string[]) => { + const phrase = arg1.length > 1 ? 'options are' : 'option is' + + return errTemplate`\ + The following configuration ${fmt.off(phrase)} invalid: + + ${fmt.listItems(arg1, { color: 'yellow' })} + + https://on.cypress.io/configuration + ` + }, + PLUGINS_RUN_EVENT_ERROR: (arg1: string, arg2: Error) => { + return errTemplate`\ + An error was thrown in your plugins file while executing the handler for the ${fmt.highlight(arg1)} event. + + The error we received was: + + ${fmt.stackTrace(arg2)}` + }, + CONFIG_FILE_INVALID_DEV_START_EVENT: (pluginsFilePath: string) => { + const code = errPartial` + module.exports = (on, config) => { + on('dev-server:start', () => { + ${fmt.comment('// start dev server here')} + return startDevServer(...) + } + }` + + return errTemplate`\ + To run component tests, Cypress needs you to configure the ${fmt.highlight(`dev-server:start`)} event. + + Please update this file: ${fmt.path(pluginsFilePath)} + + ${fmt.code(code)} + + https://on.cypress.io/component-testing` + }, + UNSUPPORTED_BROWSER_VERSION: (errorMsg: string) => { + return errTemplate`${fmt.off(errorMsg)}` + }, + NODE_VERSION_DEPRECATION_SYSTEM: (arg1: {name: string, value: any, configFile: string}) => { + return errTemplate`\ + Deprecation Warning: ${fmt.highlight(arg1.name)} is currently set to ${fmt.highlightSecondary(arg1.value)} in the ${fmt.highlightTertiary(arg1.configFile)} configuration file. + + As of ${fmt.cypressVersion(`9.0.0`)} the default behavior of ${fmt.highlight(arg1.name)} has changed to always use the version of Node used to start cypress via the cli. + + Please remove the ${fmt.highlight(arg1.name)} configuration option from ${fmt.highlightTertiary(arg1.configFile)}. + ` + }, + + // TODO: does this need to change since its a warning? + NODE_VERSION_DEPRECATION_BUNDLED: (arg1: {name: string, value: any, configFile: string}) => { + return errTemplate`\ + Deprecation Warning: ${fmt.highlight(arg1.name)} is currently set to ${fmt.highlightSecondary(arg1.value)} in the ${fmt.highlightTertiary(arg1.configFile)} configuration file. + + As of ${fmt.cypressVersion(`9.0.0`)} the default behavior of ${fmt.highlight(arg1.name)} has changed to always use the version of Node used to start cypress via the cli. + + When ${fmt.highlight(arg1.name)} is set to ${fmt.highlightSecondary(arg1.value)}, Cypress will use the version of Node bundled with electron. This can cause problems running certain plugins or integrations. + + As the ${fmt.highlight(arg1.name)} configuration option will be removed in a future release, it is recommended to remove the ${fmt.highlight(arg1.name)} configuration option from ${fmt.highlightTertiary(arg1.configFile)}. + ` + }, + + // V10 Added: + + MULTIPLE_SUPPORT_FILES_FOUND: (arg1: string, arg2: string[]) => { + return errTemplate`\ + There were multiple support files found matching your ${fmt.highlightSecondary(`supportFile`)} pattern. + + Your supportFile is set to: ${fmt.highlight(arg1)} + + We found the following files: + + ${fmt.listItems(arg2)} + + Please remove or combine the support files into a single file.` + }, + + CONFIG_FILE_MIGRATION_NEEDED: (projectRoot: string) => { + return errTemplate` + There is a ${fmt.highlight(`cypress.json`)} file at the path: ${fmt.path(projectRoot)} + + ${fmt.cypressVersion('10.0.0')} no longer supports cypress.json. + + Please run ${fmt.highlightTertiary('cypress open')} to launch the migration tool to migrate to ${fmt.highlightSecondary('cypress.config.{ts|js}')}. + ` + }, + + LEGACY_CONFIG_FILE: (baseFileName: string, projectRoot: string) => { + return errTemplate` + There is both a ${fmt.highlight(baseFileName)} and a ${fmt.highlight(`cypress.json`)} file at the location below: + + ${fmt.path(projectRoot)} + + Cypress no longer supports cypress.json, please remove it from your project. + ` + }, + + SETUP_NODE_EVENTS_DO_NOT_SUPPORT_DEV_SERVER: (configFilePath: string) => { + const code = errPartial` + { + component: { + devServer (cypressDevServerConfig, devServerConfig) { + ${fmt.comment(`// start dev server here`) + } + } + }` + + return errTemplate`\ + Your ${fmt.highlightSecondary(`configFile`)} is invalid: ${fmt.path(configFilePath)} + + Binding to the ${fmt.highlightSecondary(`on('dev-server:start')`)} event is no longer necessary. + + Please update your code to use the ${fmt.highlight(`component.devServer()`)} function. + + ${fmt.code(code)} + + Learn more: https://on.cypress.io/dev-server + ` + }, + + CONFIG_FILE_INVALID_ROOT_CONFIG: (errShape: BreakingErrResult) => { + const code = errPartial` + { + e2e: { + specPattern: '...', + }, + component: { + specPattern: '...', + }, + }` + + return errTemplate`\ + The ${fmt.highlight(errShape.name)} configuration option is now invalid when set from the root of the config object in ${fmt.cypressVersion(`10.0.0`)}. + + It is now configured separately as a testing type property: ${fmt.highlightSecondary(`e2e.${errShape.name}`)} and ${fmt.highlightSecondary(`component.${errShape.name}`)} + + ${fmt.code(code)} + + https://on.cypress.io/migration-guide` + }, + + CONFIG_FILE_INVALID_ROOT_CONFIG_E2E: (errShape: BreakingErrResult) => { + const code = errPartial` + { + e2e: { + ${fmt.off(errShape.name)}: '...', + } + }` + + return errTemplate`\ + The ${fmt.highlight(errShape.name)} configuration option is now invalid when set from the root of the config object in ${fmt.cypressVersion(`10.0.0`)}. + + It is now configured separately as a testing type property: ${fmt.highlightSecondary(`e2e.${errShape.name}`)} + + ${fmt.code(code)} + + https://on.cypress.io/migration-guide` + }, + + // TODO: add path to config file + CONFIG_FILE_INVALID_TESTING_TYPE_CONFIG_COMPONENT: (errShape: BreakingErrResult) => { + const code = errPartial` + { + e2e: { + ${fmt.off(errShape.name)}: '...', + } + }` + + return errTemplate`\ + The ${fmt.highlight(`component.${errShape.name}`)} configuration option is not valid for component testing. + + Please remove this option or add this as an e2e testing type property: ${fmt.highlightSecondary(`e2e.${errShape.name}`)} + + ${fmt.code(code)} + + https://on.cypress.io/migration-guide` + }, + + CONFIG_FILE_DEV_SERVER_IS_NOT_A_FUNCTION: (configFilePath: string, setupNodeEvents: any) => { + const code = errPartial` + { + component: { + devServer (cypressDevServerConfig, devServerConfig) { + ${fmt.comment(`// start dev server here`) + } + } + }` + + return errTemplate`\ + Your ${fmt.highlightSecondary(`configFile`)} is invalid: ${fmt.path(configFilePath)} + + The ${fmt.highlight(`component.devServer()`)} must be a function with the following signature: + + ${fmt.code(code)} + + Instead, we saw: + + ${fmt.stringify(setupNodeEvents)} + + Learn more: https://on.cypress.io/dev-server + ` + }, + +} as const + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +const _typeCheck: Record ErrTemplateResult> = AllCypressErrors + +type AllCypressErrorObj = typeof AllCypressErrors + +export type AllCypressErrorNames = keyof typeof AllCypressErrors + +export function getMsgByType (type: Type, ...args: Parameters): string { + const err = getError(type, ...args) + + return err.message +} + +/** + * Given an error name & params for the error, returns a "CypressError", + * with a forBrowser property, used when we want to format the value for sending to + * the browser rather than the terminal. + * + * @param type + * @param args + * @returns + */ +export const getError = function (type: Type, ...args: Parameters): CypressError { + // If we don't know this "type" of error, return as a non-cypress error + if (!AllCypressErrors[type]) { + const err = new Error(`UNKNOWN ERROR ${JSON.stringify(type)}`) as CypressError + + err.isCypressErr = false + err.type = type + err.messageMarkdown = err.message + + return err + } + + // @ts-expect-error + const result = AllCypressErrors[type](...args) as ErrTemplateResult + + const { message, details, originalError, messageMarkdown } = result + + const err = new Error(message) as CypressError + + err.isCypressErr = true + err.type = type + err.details = details + err.messageMarkdown = messageMarkdown + err.originalError = originalError + + if (originalError) { + err.stack = originalError.stack + err.stackWithoutMessage = stackWithoutMessage(originalError.stack ?? '') + } else { + const newErr = new Error() + + Error.captureStackTrace(newErr, getError) + err.stack = newErr.stack + err.stackWithoutMessage = stackWithoutMessage(err.stack ?? '') + } + + return err +} + +export const logWarning = function (type: Type, ...args: Parameters) { + const err = getError(type, ...args) + + logError(err, 'magenta') + + return null +} + +export const throwErr = function (type: Type, ...args: Parameters) { + const err = getError(type, ...args) + + if (!err.originalError) { + Error.captureStackTrace(err, throwErr) + err.stackWithoutMessage = stackWithoutMessage(err.stack ?? '') + } + + throw err +} + +// For when the error is passed via the socket-base +interface GenericError extends Error { + forBrowser?: never + stackWithoutMessage?: never + [key: string]: any +} + +export const cloneErr = function (err: CypressError | GenericError, options: {html?: boolean} = {}) { + _.defaults(options, { + html: false, + }) + + // pull off these properties + const obj = _.pick(err, 'message', 'messageMarkdown', 'type', 'name', 'stack', 'fileName', 'lineNumber', 'columnNumber') as ClonedError + + if (options.html) { + obj.message = ansi_up.ansi_to_html(err.message) + // revert back the distorted characters + // in case there is an error in a child_process + // that contains quotes + .replace(/\&\#x27;/g, '\'') + .replace(/\"\;/g, '"') + } + + // and any own (custom) properties + // of the err object + Object.entries(err || {}).forEach(([prop, val]) => { + obj[prop] = val + }) + + if (err.stackWithoutMessage) { + obj.stack = err.stackWithoutMessage + } + + return obj +} + +export { + stripAnsi, + getError as get, + logWarning as warning, +} + +// Re-exporting old namespaces for legacy server access +export { + logError as log, + isCypressErr, +} from './errorUtils' diff --git a/packages/errors/src/index.ts b/packages/errors/src/index.ts new file mode 100644 index 000000000000..63d3c1ffcdb8 --- /dev/null +++ b/packages/errors/src/index.ts @@ -0,0 +1,13 @@ +import * as errorsApi from './errors' +import * as errorUtils from './errorUtils' +import * as stackUtils from './stackUtils' + +export { theme } from './errTemplate' + +export { stackUtils, errorUtils } + +export * from './errors' + +export * from './errorTypes' + +export default errorsApi diff --git a/packages/server/lib/util/stack_utils.ts b/packages/errors/src/stackUtils.ts similarity index 61% rename from packages/server/lib/util/stack_utils.ts rename to packages/errors/src/stackUtils.ts index 1018a367a2a5..7e95ce96cbee 100644 --- a/packages/server/lib/util/stack_utils.ts +++ b/packages/errors/src/stackUtils.ts @@ -1,7 +1,10 @@ import _ from 'lodash' +import type { ErrorLike } from './errorTypes' const stackLineRegex = /^\s*(at )?.*@?\(?.*\:\d+\:\d+\)?$/ +type MessageLines = [string[], string[]] & {messageEnded?: boolean} + // returns tuple of [message, stack] export const splitStack = (stack: string) => { const lines = stack.split('\n') @@ -15,24 +18,28 @@ export const splitStack = (stack: string) => { } return memo - }, [[], []] as any[] & {messageEnded: boolean}) + }, [[], []] as MessageLines) } -export const unsplitStack = (messageLines, stackLines) => { +export const unsplitStack = (messageLines: string | string[], stackLines: string[]) => { return _.castArray(messageLines).concat(stackLines).join('\n') } -export const getStackLines = (stack) => { +export const getStackLines = (stack: string) => { const [, stackLines] = splitStack(stack) return stackLines } -export const stackWithoutMessage = (stack) => { +/** + * Takes the stack and returns only the lines that contain stack-frame like entries, + * matching the `stackLineRegex` above + */ +export const stackWithoutMessage = (stack: string) => { return getStackLines(stack).join('\n') } -export const replacedStack = (err, newStack) => { +export const replacedStack = (err: ErrorLike, newStack: string) => { // if err already lacks a stack or we've removed the stack // for some reason, keep it stackless if (!err.stack) return err.stack diff --git a/packages/server/lib/util/strip_indent.js b/packages/errors/src/stripIndent.ts similarity index 75% rename from packages/server/lib/util/strip_indent.js rename to packages/errors/src/stripIndent.ts index eac57e876b9a..886d04811f57 100644 --- a/packages/server/lib/util/strip_indent.js +++ b/packages/errors/src/stripIndent.ts @@ -1,5 +1,5 @@ -const stripIndent = (strings, ...args) => { - const parts = [] +export const stripIndent = (strings: TemplateStringsArray, ...args: any[]): string => { + const parts: any[] = [] for (let i = 0; i < strings.length; i++) { parts.push(strings[i]) @@ -10,7 +10,7 @@ const stripIndent = (strings, ...args) => { } const lines = parts.join('').split('\n') - const firstLine = lines[0].length === 0 ? lines[1] : lines[0] + const firstLine = (lines[0]?.length === 0 ? lines[1] : lines[0]) ?? '' let indentSize = 0 for (let i = 0; i < firstLine.length; i++) { @@ -32,7 +32,3 @@ const stripIndent = (strings, ...args) => { return result } - -module.exports = { - stripIndent, -} diff --git a/packages/errors/test/mocha.opts b/packages/errors/test/mocha.opts new file mode 100644 index 000000000000..69187492696b --- /dev/null +++ b/packages/errors/test/mocha.opts @@ -0,0 +1,7 @@ +test/unit +-r @packages/ts/register +--recursive +--extension=js,ts +--reporter mocha-multi-reporters +--reporter-options configFile=../../mocha-reporter-config.json +--exit \ No newline at end of file diff --git a/packages/errors/test/support/error-comparison-tool.ts b/packages/errors/test/support/error-comparison-tool.ts new file mode 100644 index 000000000000..14a8062ec03d --- /dev/null +++ b/packages/errors/test/support/error-comparison-tool.ts @@ -0,0 +1,223 @@ +/* eslint-disable no-console */ +import express from 'express' +import fs from 'fs-extra' +import globby from 'globby' +import Markdown from 'markdown-it' +import path from 'path' +import { WIDTH } from './utils' + +const ERRORS_DIR = path.join(__dirname, '..', '..') +const SNAPSHOT_HTML = path.join(ERRORS_DIR, '__snapshot-html__') +const SNAPSHOT_HTML_LOCAL = path.join(ERRORS_DIR, '__snapshot-html-local__') +const SNAPSHOT_MARKDOWN = path.join(ERRORS_DIR, '__snapshot-md__') + +const app = express() + +const LINKS = `
Ansi Compare | Ansi Base List | Markdown |
` + +const SEARCH_HANDLER = ` + +` + +const getFiles = async (baseDir: string, spec?: string) => { + const pattern = spec ? `${spec}*` : '**/*' + + return (await globby(`${baseDir}/${pattern}`)) +} + +async function getRows (offset = 0, baseList: boolean = false, spec?: string) { + const baseDir = baseList ? SNAPSHOT_HTML : SNAPSHOT_HTML_LOCAL + const toCompare = await getFiles(baseDir, spec) + + const rows = toCompare.filter((f) => f.endsWith('.html')).sort().slice(offset, offset + 10).map((f) => path.basename(f).split('.')[0]).map((name) => { + const width = baseList ? WIDTH : 550 + // const height = baseList ? HEIGHT : 600 + const height = 400 + + return ` + + ${name} + + ${baseList ? '' : ` + + + `} + ` + }) + + if (toCompare.length > offset + 10) { + rows.push(``) + } + + return rows.join('\n') +} + +app.get('/', async (req, res) => { + try { + const rows = await getRows() + + res.type('html').send(` + + + ${LINKS} + + + + + + ${rows} + +
TableOriginalNew
+ `) + } catch (e) { + res.json({ errStack: e.stack }) + } +}) + +app.get('/base-list', async (req, res) => { + const spec = req.query.spec as string + + try { + const rows = await getRows(0, true, spec) + + res.type('html').send(` + + + ${LINKS} + ${SEARCH_HANDLER} + + + + + + ${rows} + +
TableOriginal
+ `) + } catch (e) { + res.json({ errStack: e.stack }) + } +}) + +app.get<{offset: number}>('/load-more/:offset', async (req, res) => { + const rows = await getRows(req.params.offset) + + res.send(rows) +}) + +app.get<{offset: number}>('/load-more-base/:offset', async (req, res) => { + const rows = await getRows(req.params.offset, true) + + res.send(rows) +}) + +app.get('/looks-good/:name', async (req, res) => { + try { + await fs.move( + path.join(SNAPSHOT_HTML_LOCAL, `${req.params.name}.html`), + path.join(SNAPSHOT_HTML, `${req.params.name}.html`), + { overwrite: true }, + ) + + res.json({ ok: true }) + } catch (e) { + res.status(400).json({ stack: e.stack }) + } +}) + +app.get<{name: string, type: string}>('/html/:name/:type', async (req, res) => { + const pathToFile = path.join(ERRORS_DIR, req.params.type, `${req.params.name}.html`) + + try { + const contents = await fs.readFile(pathToFile, 'utf8') + + res.type('html').send(contents.replace(/\/g, '').replace('overflow: hidden;', '')) + } catch (e) { + res.json({ errStack: e }) + } +}) + +app.get('/md', async (req, res) => { + const spec = req.query.spec as string + + try { + const toRender = (await getFiles(SNAPSHOT_MARKDOWN, spec)).filter((f) => f.endsWith('.md')).sort() + const markdownContents = await Promise.all(toRender.map((f) => fs.readFile(f, 'utf8'))) + const md = new Markdown({ + html: true, + linkify: true, + }) + + res.type('html').send(` + + ${LINKS} + ${SEARCH_HANDLER} + +
+ ${toRender.map((r, i) => { + return `
+
${path.basename(r).split('.')[0]}
+
+
${md.render(markdownContents[i] ?? '')}
+
${markdownContents[i] ?? ''}
+
+
` + }).join('\n')} +
+ `) + } catch (e) { + res.json({ stack: e.stack }) + } +}) + +app.listen(5555, () => { + console.log(`Comparison server listening on: http://localhost:5555`) +}) diff --git a/packages/errors/test/support/utils.ts b/packages/errors/test/support/utils.ts new file mode 100644 index 000000000000..e71b6272c8bb --- /dev/null +++ b/packages/errors/test/support/utils.ts @@ -0,0 +1,95 @@ +import Debug from 'debug' +import { app, BrowserWindow } from 'electron' +import fse from 'fs-extra' +import path from 'path' +import { PNG } from 'pngjs' + +const isCi = require('is-ci') + +if (app) { + app.on('window-all-closed', () => { + }) +} + +export const HEIGHT = 600 + +export const WIDTH = 1200 + +const EXT = '.png' +const debug = Debug(isCi ? '*' : 'visualSnapshotErrors') + +export const copyImageToBase = (from: string, to: string) => { + return fse.copy(from, to, { overwrite: true }) +} + +export const convertHtmlToImage = async (htmlFile: string, snapshotImagesFolder: string) => { + const win = new BrowserWindow({ + show: false, + width: WIDTH, + height: HEIGHT, + }) + + try { + await app.isReady() + + win.webContents.debugger.attach() + + debug(`Loading %s`, htmlFile) + + await win.loadFile(htmlFile) + + await win.webContents.debugger.sendCommand('Emulation.setDeviceMetricsOverride', { + width: WIDTH, + height: HEIGHT, + deviceScaleFactor: 1, + mobile: false, + }) + + const { data } = await win.webContents.debugger.sendCommand('Page.captureScreenshot', { + format: 'png', + quality: 100, + }) + + const imagePath = htmlFile.replace('.html', EXT) + const snapshotImagePath = path.join(snapshotImagesFolder, path.basename(imagePath)) + + debug('snapshotImagePath %s', snapshotImagePath) + + const receivedImageBuffer = Buffer.from(data, 'base64') + const receivedPng = PNG.sync.read(receivedImageBuffer) + const receivedPngBuffer = PNG.sync.write(receivedPng) + + await fse.outputFile(snapshotImagePath, receivedPngBuffer) + + // - if image does not exist in __snapshot-bases__ + // then copy into __snapshot-bases__ + // - if image does exist then diff if, and if its + // greater than >.01 diff, then copy it in + // - unless we're in CI, then fail if there's a diff + // try { + // const buf = await fse.readFile(snapshotImagePath) + // const existingPng = PNG.sync.read(buf) + // const diffPng = new PNG({ width: WIDTH, height: HEIGHT }) + // const changed = pixelmatch(existingPng.data, receivedPng.data, diffPng.data, WIDTH, HEIGHT, { threshold: 0.3 }) + + // debug('num pixels different: %s', changed) + + // if (changed > 100) { + // if (isCi) { + // throw new Error(`Image difference detected. Base error image no longer matches for file: ${snapshotImagePath}, off by ${changed} pixels`) + // } + + // await copyImageToBase(imagePath, snapshotImagePath) + // } + // } catch (e: any) { + // if (e.code === 'ENOENT') { + // debug(`Adding new image: ${imagePath}`) + // await copyImageToBase(imagePath, snapshotImagePath) + // } else { + // throw e + // } + // } + } finally { + win.destroy() + } +} diff --git a/packages/errors/test/unit/errTemplate_spec.ts b/packages/errors/test/unit/errTemplate_spec.ts new file mode 100644 index 000000000000..df39b358e4e9 --- /dev/null +++ b/packages/errors/test/unit/errTemplate_spec.ts @@ -0,0 +1,78 @@ +import { expect } from 'chai' +import chalk from 'chalk' +import { errTemplate, fmt, theme } from '../../src/errTemplate' +import { stripIndent } from '../../src/stripIndent' + +describe('errTemplate', () => { + it('returns an object w/ basic props & forBrowser', () => { + const obj = errTemplate`Hello world` + + expect(obj).to.include({ message: 'Hello world' }) + expect(obj).to.include({ messageMarkdown: 'Hello world' }) + }) + + it('colors yellow by default for the console, backticks passed arguments for the browser,', () => { + const obj = errTemplate`Hello world ${fmt.highlight('special')}` + + expect(obj).to.include({ message: `Hello world ${chalk.yellow('special')}` }) + expect(obj).to.include({ messageMarkdown: 'Hello world `special`' }) + }) + + it('uses fmt.off to guard passed values', () => { + const obj = errTemplate`Hello world ${fmt.off('special')}` + + expect(obj).to.include({ message: `Hello world special` }) + expect(obj).to.include({ messageMarkdown: `Hello world special` }) + }) + + it('will stringify non scalar values', () => { + const someObj = { a: 1, b: 2, c: 3 } + const obj = errTemplate` + This was returned from the app: + + ${fmt.highlightTertiary(someObj)}` + + expect(obj).to.include({ + messageMarkdown: stripIndent` + This was returned from the app: + + \`\`\` + ${JSON.stringify(someObj, null, 2)} + \`\`\``, + }) + + expect(obj).to.include({ + message: stripIndent` + This was returned from the app: + + ${theme.blue(JSON.stringify(someObj, null, 2))}`, + }) + }) + + it('sets originalError, for toErrorProps, highlight stack for console', () => { + const specFile = 'specFile.js' + const err = new Error() + const obj = errTemplate` + This was an error in ${fmt.highlight(specFile)} + + ${fmt.stackTrace(err)}` + + expect(obj).to.include({ messageMarkdown: `This was an error in \`specFile.js\`` }) + expect(obj).to.include({ + message: `This was an error in ${chalk.yellow(specFile)}`, + details: err.stack ?? '', + }) + }) + + it('throws if multiple details are used in the same template', () => { + expect(() => { + errTemplate` + Hello world + + ${fmt.stackTrace(new Error())} + + ${fmt.stackTrace(new Error())} + ` + }).to.throw(/Cannot use fmt.stackTrace\(\) multiple times in the same errTemplate/) + }) +}) diff --git a/packages/errors/test/unit/errors_spec.ts b/packages/errors/test/unit/errors_spec.ts new file mode 100644 index 000000000000..61f15f6f5ef5 --- /dev/null +++ b/packages/errors/test/unit/errors_spec.ts @@ -0,0 +1,143 @@ +import 'sinon-chai' +import style from 'ansi-styles' +import chai, { expect } from 'chai' +/* eslint-disable no-console */ +import chalk from 'chalk' +import sinon from 'sinon' +import * as errors from '../../src' +import { parseResolvedPattern } from '../../src/errorUtils' + +chai.use(require('@cypress/sinon-chai')) + +describe('lib/errors', () => { + beforeEach(() => { + sinon.restore() + sinon.spy(console, 'log') + }) + + context('.log', () => { + it('uses red by default', () => { + const err = errors.get('NOT_LOGGED_IN') + + const ret = errors.log(err) + + expect(ret).to.be.undefined + + const { + red, + } = style + + expect(console.log).to.be.calledWithMatch(red.open) + + expect(console.log).to.be.calledWithMatch(red.close) + }) + + it('can change the color', () => { + const err = errors.get('NOT_LOGGED_IN') + + const ret = errors.log(err, 'yellow') + + expect(ret).to.be.undefined + + const { + yellow, + } = style + + expect(console.log).to.be.calledWithMatch(yellow.open) + + expect(console.log).to.be.calledWithMatch(yellow.close) + }) + + it('logs err.message', () => { + const err = errors.getError('NO_PROJECT_ID', '/path/to/project/cypress.json') + + const ret = errors.log(err) + + expect(ret).to.be.undefined + + expect(console.log).to.be.calledWithMatch('/path/to/project/cypress.json') + }) + + it('logs err.details', () => { + const userError = new Error('asdf') + + const err = errors.get('CONFIG_FILE_UNEXPECTED_ERROR', 'foo/bar/baz', userError) + + const ret = errors.log(err) + + expect(ret).to.be.undefined + + expect(console.log).to.be.calledWithMatch('foo/bar/baz') + + expect(console.log).to.be.calledWithMatch(chalk.magenta(userError.stack ?? '')) + }) + + it('logs err.stack in development', () => { + process.env.CYPRESS_INTERNAL_ENV = 'development' + + const err = new Error('foo') + + const ret = errors.log(err) + + expect(ret).to.eq(err) + + expect(console.log).to.be.calledWith(chalk.red(err.stack ?? '')) + }) + }) + + context('.clone', () => { + it('converts err.message from ansi to html with span classes when html true', () => { + const err = new Error(`foo${chalk.blue('bar')}${chalk.yellow('baz')}`) + const obj = errors.cloneErr(err, { html: true }) + + expect(obj.message).to.eq('foobarbaz') + }) + + it('does not convert err.message from ansi to html when no html option', () => { + const err = new Error(`foo${chalk.blue('bar')}${chalk.yellow('baz')}`) + const obj = errors.cloneErr(err) + + expect(obj.message).to.eq('foo\u001b[34mbar\u001b[39m\u001b[33mbaz\u001b[39m') + }) + }) + + describe('.parseResolvedPattern', () => { + const folderPath = '/dev/cypress/packages/server' + + it('splits common paths', () => { + const pattern = '/dev/cypress/packages/server/cypress/integration/**notfound**' + + const [resolvedBasePath, resolvedPattern] = parseResolvedPattern(folderPath, pattern) + + expect(resolvedBasePath).to.eq('/dev/cypress/packages/server') + expect(resolvedPattern).to.eq('cypress/integration/**notfound**') + }) + + it('splits common paths factoring in ../', () => { + const pattern = '/dev/cypress/packages/server/../../integration/**notfound**' + + const [resolvedBasePath, resolvedPattern] = parseResolvedPattern(folderPath, pattern) + + expect(resolvedBasePath).to.eq('/dev/cypress') + expect(resolvedPattern).to.eq('integration/**notfound**') + }) + + it('splits common paths until falsy instead of doing an intersection', () => { + const pattern = '/private/var/cypress/integration/cypress/integration/**notfound**' + + const [resolvedBasePath, resolvedPattern] = parseResolvedPattern(folderPath, pattern) + + expect(resolvedBasePath).to.eq('') + expect(resolvedPattern).to.eq('/private/var/cypress/integration/cypress/integration/**notfound**') + }) + + it('splits common paths up directories until root is reached', () => { + const pattern = '/../../../../../../../cypress/integration/**notfound**' + + const [resolvedBasePath, resolvedPattern] = parseResolvedPattern(folderPath, pattern) + + expect(resolvedBasePath).to.eq('') + expect(resolvedPattern).to.eq('/cypress/integration/**notfound**') + }) + }) +}) diff --git a/packages/server/test/unit/util/strip_indent.ts b/packages/errors/test/unit/stripIndent_spec.ts similarity index 83% rename from packages/server/test/unit/util/strip_indent.ts rename to packages/errors/test/unit/stripIndent_spec.ts index c1d1fac674b6..bcc720de0cca 100644 --- a/packages/server/test/unit/util/strip_indent.ts +++ b/packages/errors/test/unit/stripIndent_spec.ts @@ -1,9 +1,7 @@ -import '../../spec_helper' - import { expect } from 'chai' -import { stripIndent } from '../../../lib/util/strip_indent' +import { stripIndent } from '../../src/stripIndent' -describe('lib/util/strip_indent', () => { +describe('src/stripIndent', () => { it('does not trip right end', () => { const str = stripIndent`\ There was an error reconnecting to the Chrome DevTools protocol. Please restart the browser. diff --git a/packages/errors/test/unit/visualSnapshotErrors_spec.ts b/packages/errors/test/unit/visualSnapshotErrors_spec.ts new file mode 100644 index 000000000000..39367a13f885 --- /dev/null +++ b/packages/errors/test/unit/visualSnapshotErrors_spec.ts @@ -0,0 +1,1085 @@ +/* eslint-disable no-console */ +import chai, { expect } from 'chai' +import Debug from 'debug' +import fse from 'fs-extra' +import globby from 'globby' +import _ from 'lodash' +import path from 'path' +import sinon, { SinonSpy } from 'sinon' +import * as errors from '../../src' +import { convertHtmlToImage } from '../support/utils' + +// For importing the files below +process.env.CYPRESS_INTERNAL_ENV = 'test' + +// require'd so the unsafe types from the server / missing types don't mix in here +const termToHtml = require('term-to-html') +const isCi = require('is-ci') +const { terminalBanner } = require('terminal-banner') +const ciProvider = require('@packages/server/lib/util/ci_provider') +const browsers = require('@packages/server/lib/browsers') +const launcherBrowsers = require('@packages/launcher/lib/browsers') + +const debug = Debug(isCi ? '*' : 'visualSnapshotErrors') + +let snapshotFailures = 0 + +after(() => { + if (snapshotFailures > 0) { + console.log(` + ================================= + + Snapshot failures see for visualSnapshotErrors. + + Run "yarn comparison" locally from the @packages/error package to resolve + + ================================= + `) + } +}) + +interface ErrorGenerator { + default: Parameters + [key: string]: Parameters +} + +type CypressErrorType = keyof typeof errors.AllCypressErrors + +chai.config.truncateThreshold = 0 +chai.use(require('@cypress/sinon-chai')) + +termToHtml.themes.dark.bg = '#111' + +const lineAndColNumsRe = /:\d+:\d+/ + +const snapshotHtmlFolder = path.join(__dirname, '..', '..', '__snapshot-html__') +const snapshotHtmlLocalFolder = path.join(__dirname, '..', '..', '__snapshot-html-local__') +const snapshotMarkdownFolder = path.join(__dirname, '..', '..', '__snapshot-md__') +const snapshotImagesFolder = path.join(__dirname, '..', '..', '__snapshot-images__') + +const saveHtml = async (filename: string, html: string) => { + await fse.outputFile(filename, html, 'utf8') +} + +const cypressRootPath = path.join(__dirname, '..', '..', '..', '..') + +const sanitize = (str: string) => { + return str + .split(lineAndColNumsRe).join('') + .split(cypressRootPath).join('cypress') +} + +const snapshotAndTestErrorConsole = async function (errorFileName: string) { + const logs = _ + .chain(consoleLog.args) + .map((args) => args.map(sanitize).join(' ')) + .join('\n') + .value() + + // if the sanitized snapshot matches, let's save the ANSI colors converted into HTML + const html = termToHtml + .strings(logs, termToHtml.themes.dark.name) + .split('color:#55F').join('color:#4ec4ff') // replace blueBright colors + .split('color:#A00').join('color:#e05561') // replace red colors + .split('color:#A50').join('color:#e5e510') // replace yellow colors + .split('color:#555').join('color:#4f5666') // replace gray colors + .split('color:#eee').join('color:#e6e6e6') // replace white colors + .split('color:#A0A').join('color:#c062de') // replace magenta colors + .split('color:#F5F').join('color:#de73ff') // replace magentaBright colors + .split('"Courier New", ').join('"Courier Prime", ') // replace font + .split('').join(` + body { + margin: 5px; + padding: 0; + overflow: hidden; + } + pre { + white-space: pre-wrap; + word-break: break-word; + -webkit-font-smoothing: antialiased; + } + + `) // remove margin/padding and force text overflow like a terminal + + if (isCi) { + expect(logs).not.to.contain('[object Object]') + } + + try { + fse.accessSync(errorFileName) + } catch (e) { + await saveHtml(errorFileName, html) + } + + const contents = await fse.readFile(errorFileName, 'utf8') + + try { + expect(contents).to.eq(html) + } catch (e) { + snapshotFailures++ + await saveHtml(errorFileName.replace('__snapshot-html__', '__snapshot-html-local__'), html) + throw e + } +} + +let consoleLog: SinonSpy + +beforeEach(() => { + sinon.restore() + consoleLog = sinon.spy(console, 'log') +}) + +afterEach(() => { + sinon.restore() +}) + +const testVisualError = (errorGeneratorFn: () => ErrorGenerator, errorType: K) => { + const variants = errorGeneratorFn() + + expect(variants).to.be.an('object') + + for (const [key, arr] of Object.entries(variants)) { + const filename = key === 'default' ? errorType : `${errorType} - ${key}` + + it(`${errorType} - ${key}`, async () => { + debug(`Converting ${filename}`) + + terminalBanner(filename) + + consoleLog.resetHistory() + + const err = errors.get(errorType, ...arr) + + if (!errors.isCypressErr(err)) { + throw new Error(`Expected Cypress Error`) + } + + errors.log(err) + + const htmlFilename = path.join(snapshotHtmlFolder, `${filename}.html`) + const mdFilename = path.join(snapshotMarkdownFolder, `${filename}.md`) + + await snapshotAndTestErrorConsole(htmlFilename) + + await fse.outputFile(mdFilename, err.messageMarkdown, 'utf8') + + debug(`Snapshotted ${htmlFilename}`) + + // dont run html -> image conversion if we're in CI / if not enabled + if (!isCi && process.env.HTML_IMAGE_CONVERSION) { + debug(`Converting ${errorType} to image`) + + await convertHtmlToImage(htmlFilename, snapshotImagesFolder) + + debug(`Conversion complete for ${errorType}`) + } + }).timeout(5000) + } +} + +const testVisualErrors = (whichError: CypressErrorType | '*', errorsToTest: {[K in CypressErrorType]: () => ErrorGenerator}) => { + // if we aren't testing all the errors + if (whichError !== '*') { + // then just test this individual error + return testVisualError(errorsToTest[whichError], whichError) + } + + // otherwise test all the errors + before(() => { + // prune out all existing local staging folders + return Promise.all([ + fse.remove(snapshotMarkdownFolder), + fse.remove(snapshotHtmlLocalFolder), + fse.remove(snapshotImagesFolder), + ]) + }) + + after(async () => { + // if we're in CI, make sure there's all the files + // we expect there to be in __snapshot-html__ + const files = await globby(`${snapshotHtmlFolder}/*`) + const errorKeys = _.keys(errors.AllCypressErrors) + + if (isCi) { + const errorNames = files.map((file) => { + return path.basename(file, '.html').split(' ')[0] + }) + const uniqErrors = _.uniq(errorNames) + // const excessErrors = _.difference(uniqErrors, _.keys(errors.AllCypressErrors)) + + // await Promise.all(excessErrors.map((file) => { + // const pathToHtml = path.join(baseImageFolder, file + EXT) + // return fse.remove(pathToHtml) + // })) + + const sortedUniqErrors = uniqErrors.sort() + const sortedErrorKeys = errorKeys.sort() + + _.each(sortedUniqErrors, (val, index) => { + expect(val).to.eq(sortedErrorKeys[index]) + }) + } else { + const errorFiles = files.map((file) => { + return { + errorType: path.basename(file, '.html').split(' ')[0], + filePath: file, + } + }) + const excessErrors = _ + .chain(errorFiles) + .map('errorType') + .uniq() + .difference(errorKeys) + .value() + + return Promise.all( + errorFiles + .filter((obj) => { + return _.includes(excessErrors, obj.errorType) + }) + .map((obj) => { + return fse.remove(obj.filePath) + }), + ) + } + }) + + // test each error visually + // @ts-expect-error + _.forEach(errorsToTest, testVisualError) + + // if we are testing all the errors then make sure we + // have a test to validate that we've written a test + // for each error type + it('ensures there are matching tests for each cypress error', () => { + const { missingErrorTypes, excessErrorTypes } = _ + .chain(errors.AllCypressErrors) + .keys() + .thru((errorTypes) => { + const errorsToTestTypes = _.keys(errorsToTest) + + return { + missingErrorTypes: _.difference(errorTypes, errorsToTestTypes), + excessErrorTypes: _.difference(errorsToTestTypes, errorTypes), + } + }) + .value() + + expect(missingErrorTypes, 'you are missing tests around the following error types').to.be.empty + expect(excessErrorTypes, 'you have added excessive tests for errors which do not exist').to.be.empty + }) +} + +const makeApiErr = () => { + const err = new Error('500 - "Internal Server Error"') + + err.name = 'StatusCodeError' + + return err +} + +const makeErr = () => { + const err = new Error('fail whale') + + err.stack = err.stack?.split('\n').slice(0, 3).join('\n') ?? '' + + return err as Error & {stack: string} +} + +describe('visual error templates', () => { + const errorType = (process.env.ERROR_TYPE || '*') as CypressErrorType + + // testVisualErrors('CANNOT_RECORD_NO_PROJECT_ID', { + testVisualErrors(errorType, { + CANNOT_TRASH_ASSETS: () => { + const err = makeErr() + + return { + default: [err], + } + }, + CANNOT_REMOVE_OLD_BROWSER_PROFILES: () => { + const err = makeErr() + + return { + default: [err], + } + }, + VIDEO_RECORDING_FAILED: () => { + const err = makeErr() + + return { + default: [err], + } + }, + VIDEO_POST_PROCESSING_FAILED: () => { + const err = makeErr() + + return { + default: [err], + } + }, + CHROME_WEB_SECURITY_NOT_SUPPORTED: () => { + return { + default: ['firefox'], + } + }, + BROWSER_NOT_FOUND_BY_NAME: () => { + return { + default: ['invalid-browser', browsers.formatBrowsersToOptions(launcherBrowsers.browsers)], + canary: ['canary', browsers.formatBrowsersToOptions(launcherBrowsers.browsers)], + } + }, + BROWSER_NOT_FOUND_BY_PATH: () => { + const err = makeErr() + + return { + default: ['/path/does/not/exist', err.message], + } + }, + NOT_LOGGED_IN: () => { + return { + default: [], + } + }, + TESTS_DID_NOT_START_RETRYING: () => { + return { + default: ['Retrying...'], + retryingAgain: ['Retrying again...'], + } + }, + TESTS_DID_NOT_START_FAILED: () => { + return { + default: [], + } + }, + DASHBOARD_CANCEL_SKIPPED_SPEC: () => { + return { + default: [], + } + }, + DASHBOARD_API_RESPONSE_FAILED_RETRYING: () => { + return { + default: [{ + tries: 3, + delay: 5000, + response: makeApiErr(), + }], + lastTry: [{ + tries: 1, + delay: 5000, + response: makeApiErr(), + }], + } + }, + DASHBOARD_CANNOT_PROCEED_IN_PARALLEL: () => { + return { + default: [{ + flags: { + ciBuildId: 'invalid', + group: 'foo', + }, + response: makeApiErr(), + }], + } + }, + DASHBOARD_CANNOT_PROCEED_IN_SERIAL: () => { + return { + default: [{ + flags: { + ciBuildId: 'invalid', + group: 'foo', + }, + response: makeApiErr(), + }], + } + }, + DASHBOARD_UNKNOWN_INVALID_REQUEST: () => { + return { + default: [{ + flags: { + ciBuildId: 'invalid', + group: 'foo', + }, + response: makeApiErr(), + }], + } + }, + DASHBOARD_UNKNOWN_CREATE_RUN_WARNING: () => { + return { + default: [{ + props: { + code: 'OUT_OF_TIME', + name: 'OutOfTime', + hadTime: 1000, + spentTime: 999, + }, + message: 'You are almost out of time', + }], + } + }, + DASHBOARD_STALE_RUN: () => { + return { + default: [{ + runUrl: 'https://dashboard.cypress.io/project/abcd/runs/1', + tag: '123', + group: 'foo', + parallel: true, + }], + } + }, + DASHBOARD_ALREADY_COMPLETE: () => { + return { + default: [{ + runUrl: 'https://dashboard.cypress.io/project/abcd/runs/1', + tag: '123', + group: 'foo', + parallel: true, + }], + } + }, + DASHBOARD_PARALLEL_REQUIRED: () => { + return { + default: [{ + runUrl: 'https://dashboard.cypress.io/project/abcd/runs/1', + tag: '123', + group: 'foo', + parallel: true, + }], + } + }, + DASHBOARD_PARALLEL_DISALLOWED: () => { + return { + default: [{ + runUrl: 'https://dashboard.cypress.io/project/abcd/runs/1', + tag: '123', + group: 'foo', + parallel: true, + }], + } + }, + DASHBOARD_PARALLEL_GROUP_PARAMS_MISMATCH: () => { + return { + default: [ + { + group: 'foo', + runUrl: 'https://dashboard.cypress.io/project/abcd/runs/1', + ciBuildId: 'test-ciBuildId-123', + parameters: { + osName: 'darwin', + osVersion: 'v1', + browserName: 'Electron', + browserVersion: '59.1.2.3', + specs: [ + 'cypress/integration/app_spec.js', + ], + }, + }, + ], + } + }, + DASHBOARD_RUN_GROUP_NAME_NOT_UNIQUE: () => { + return { + default: [{ + runUrl: 'https://dashboard.cypress.io/project/abcd/runs/1', + tag: '123', + group: 'foo', + parallel: true, + }], + } + }, + DEPRECATED_BEFORE_BROWSER_LAUNCH_ARGS: () => { + return { + default: [], + } + }, + DUPLICATE_TASK_KEY: () => { + const tasks = ['foo', 'bar', 'baz'] + + return { + default: [tasks], + } + }, + INDETERMINATE_CI_BUILD_ID: () => { + return { + default: [{ + group: 'foo', + parallel: 'false', + }, + ciProvider.detectableCiBuildIdProviders()], + } + }, + RECORD_PARAMS_WITHOUT_RECORDING: () => { + return { + default: [{ parallel: 'true' }], + } + }, + INCORRECT_CI_BUILD_ID_USAGE: () => { + return { + default: [{ ciBuildId: 'ciBuildId123' }], + } + }, + RECORD_KEY_MISSING: () => { + return { + default: [], + } + }, + CANNOT_RECORD_NO_PROJECT_ID: () => { + return { + default: ['/path/to/cypress.json'], + } + }, + PROJECT_ID_AND_KEY_BUT_MISSING_RECORD_OPTION: () => { + return { + default: ['project-id-123'], + } + }, + DASHBOARD_INVALID_RUN_REQUEST: () => { + return { + default: [{ + message: 'request should follow postRunRequest@2.0.0 schema', + errors: [ + 'data.commit has additional properties', + 'data.ci.buildNumber is required', + ], + object: { + foo: 'foo', + bar: 'bar', + baz: 'baz', + }, + }], + } + }, + RECORDING_FROM_FORK_PR: () => { + return { + default: [], + } + }, + DASHBOARD_CANNOT_UPLOAD_RESULTS: () => { + const err = makeApiErr() + + return { + default: [err], + } + }, + DASHBOARD_CANNOT_CREATE_RUN_OR_INSTANCE: () => { + const err = makeApiErr() + + return { + default: [err], + } + }, + DASHBOARD_RECORD_KEY_NOT_VALID: () => { + return { + default: ['record-key-123', 'project-id-123'], + } + }, + DASHBOARD_PROJECT_NOT_FOUND: () => { + return { + default: ['project-id-123', '/path/to/cypress.json'], + } + }, + NO_PROJECT_ID: () => { + return { + default: ['/path/to/project/cypress.json'], + } + }, + NO_PROJECT_FOUND_AT_PROJECT_ROOT: () => { + return { + default: ['/path/to/project'], + } + }, + CANNOT_FETCH_PROJECT_TOKEN: () => { + return { + default: [], + } + }, + CANNOT_CREATE_PROJECT_TOKEN: () => { + return { + default: [], + } + }, + PORT_IN_USE_SHORT: () => { + return { + default: [2020], + } + }, + PORT_IN_USE_LONG: () => { + return { + default: [2020], + } + }, + ERROR_READING_FILE: () => { + return { + default: ['/path/to/read/file.ts', makeErr()], + } + }, + ERROR_WRITING_FILE: () => { + return { + default: ['/path/to/write/file.ts', makeErr()], + } + }, + NO_SPECS_FOUND: () => { + return { + default: ['/path/to/project/root', '**_spec.js'], + pathCommonPattern: ['/path/to/project/root', ['../**_spec.js', '../**/*.cy.*']], + pathNoCommonPattern: ['/path/to/project/root', ['/foo/*_spec.js']], + arrPattern: ['/path/to/project/root', ['**_spec.js', '**/*.cy.*']], + noPattern: ['/path/to/project/root'], + } + }, + RENDERER_CRASHED: () => { + return { + default: [], + } + }, + AUTOMATION_SERVER_DISCONNECTED: () => { + return { + default: [], + } + }, + SUPPORT_FILE_NOT_FOUND: () => { + return { + default: ['/path/to/supportFile'], + } + }, + CONFIG_FILE_REQUIRE_ERROR: () => { + const err = makeErr() + + return { + default: ['/path/to/cypress.config.js', err], + } + }, + SETUP_NODE_EVENTS_IS_NOT_FUNCTION: () => { + return { + default: ['/path/to/cypress.config.js', 'e2e', { some: 'object' }], + string: ['/path/to/cypress.config.js', 'component', 'some string'], + array: ['/path/to/cypress.config.js', 'component', ['some', 'array']], + } + }, + CONFIG_FILE_SETUP_NODE_EVENTS_ERROR: () => { + return { + default: ['/path/to/cypress.config.js', 'e2e', makeErr()], + component: ['/path/to/cypress.config.js', 'component', makeErr()], + } + }, + CONFIG_FILE_UNEXPECTED_ERROR: () => { + const err = makeErr() + + return { + default: ['/path/to/cypress.config.js', err], + } + }, + PLUGINS_INVALID_EVENT_NAME_ERROR: () => { + const err = makeErr() + + return { + default: [ + '/path/to/cypress.config.js', + 'invalid:event', + ['foo', 'bar', 'baz'], + err, + ], + } + }, + BUNDLE_ERROR: () => { + const err = makeErr() + + return { + default: ['/path/to/file', err.message], + } + }, + CONFIG_VALIDATION_ERROR: () => { + return { + default: ['configFile', 'cypress.json', { + key: 'defaultCommandTimeout', + type: 'a number', + value: false, + }], + list: ['configFile', 'cypress.json', { + key: 'displayName', + type: 'a non-empty string', + value: { name: 'chrome', version: '1.2.3', displayName: null }, + list: 'browsers', + }], + invalidString: ['configFile', 'cypress.json', { + key: 'defaultCommandTimeout', + type: 'a number', + value: '1234', + }], + invalidObject: ['configFile', 'cypress.json', { + key: 'defaultCommandTimeout', + type: 'a number', + value: { foo: 'bar' }, + }], + invalidArray: ['configFile', 'cypress.json', { + key: 'defaultCommandTimeout', + type: 'a number', + value: [1, 2, 3], + }], + pluginsFile: ['pluginsFile', 'cypress/plugins/index.js', { + key: 'defaultCommandTimeout', + type: 'a number', + value: false, + }], + noFileType: [null, null, { + key: 'defaultCommandTimeout', + type: 'a number', + value: false, + }], + } + }, + CONFIG_VALIDATION_MSG_ERROR: () => { + return { + default: ['configFile', 'cypress.json', '`something` was not right'], + noFileType: [null, null, '`something` was not right'], + } + }, + RENAMED_CONFIG_OPTION: () => { + return { + default: [{ name: 'oldName', newName: 'newName' }], + } + }, + CANNOT_CONNECT_BASE_URL: () => { + return { + default: [], + } + }, + CANNOT_CONNECT_BASE_URL_WARNING: () => { + return { + default: ['http://localhost:3000'], + } + }, + CANNOT_CONNECT_BASE_URL_RETRYING: () => { + return { + default: [{ + attempt: 1, + baseUrl: 'http://localhost:3000', + remaining: 60, + delay: 500, + }], + retrying: [{ + attempt: 2, + baseUrl: 'http://localhost:3000', + remaining: 60, + delay: 500, + }], + } + }, + INVALID_REPORTER_NAME: () => { + return { + default: [{ + name: 'missing-reporter-name', + paths: ['/path/to/reporter', '/path/reporter'], + error: makeErr(), + }], + } + }, + NO_DEFAULT_CONFIG_FILE_FOUND: () => { + return { + default: ['/path/to/project/root'], + } + }, + CONFIG_FILES_LANGUAGE_CONFLICT: () => { + return { + default: [ + '/path/to/project/root', + 'cypress.config.js', + 'cypress.config.ts', + ], + } + }, + CONFIG_FILE_NOT_FOUND: () => { + return { + default: ['cypress.json', '/path/to/project/root'], + } + }, + INVOKED_BINARY_OUTSIDE_NPM_MODULE: () => { + return { + default: [], + } + }, + FREE_PLAN_EXCEEDS_MONTHLY_PRIVATE_TESTS: () => { + return { + default: [{ + link: 'https://dashboard.cypress.io/project/abcd', + limit: 500, + usedTestsMessage: 'test', + }], + } + }, + FREE_PLAN_IN_GRACE_PERIOD_EXCEEDS_MONTHLY_PRIVATE_TESTS: () => { + return { + default: [{ + link: 'https://dashboard.cypress.io/project/abcd', + limit: 500, + usedTestsMessage: 'test', + gracePeriodMessage: 'the grace period ends', + }], + } + }, + PAID_PLAN_EXCEEDS_MONTHLY_PRIVATE_TESTS: () => { + return { + default: [{ + link: 'https://on.cypress.io/set-up-billing', + limit: 25000, + usedTestsMessage: 'private test', + }], + } + }, + FREE_PLAN_EXCEEDS_MONTHLY_TESTS: () => { + return { + default: [{ + link: 'https://on.cypress.io/set-up-billing', + limit: 500, + usedTestsMessage: 'test', + }], + } + }, + FREE_PLAN_IN_GRACE_PERIOD_EXCEEDS_MONTHLY_TESTS: () => { + return { + default: [{ + link: 'https://on.cypress.io/set-up-billing', + limit: 500, + usedTestsMessage: 'test', + gracePeriodMessage: 'Feb 1, 2022', + }], + } + }, + PLAN_EXCEEDS_MONTHLY_TESTS: () => { + return { + default: [{ + link: 'https://on.cypress.io/set-up-billing', + planType: 'Sprout', + limit: 25000, + usedTestsMessage: 'test', + }], + } + }, + FREE_PLAN_IN_GRACE_PERIOD_PARALLEL_FEATURE: () => { + return { + default: [{ + link: 'https://on.cypress.io/set-up-billing', + gracePeriodMessage: 'Feb 1, 2022', + }], + } + }, + PARALLEL_FEATURE_NOT_AVAILABLE_IN_PLAN: () => { + return { + default: [{ link: 'https://on.cypress.io/set-up-billing' }], + } + }, + PLAN_IN_GRACE_PERIOD_RUN_GROUPING_FEATURE_USED: () => { + return { + default: [{ + link: 'https://on.cypress.io/set-up-billing', + gracePeriodMessage: 'Feb 1, 2022', + }], + } + }, + RUN_GROUPING_FEATURE_NOT_AVAILABLE_IN_PLAN: () => { + return { + default: [{ link: 'https://on.cypress.io/set-up-billing' }], + } + }, + FIXTURE_NOT_FOUND: () => { + return { + default: ['file', ['js', 'ts', 'json']], + } + }, + BAD_POLICY_WARNING: () => { + return { + default: [[ + 'HKEY_LOCAL_MACHINE\\Software\\Policies\\Google\\Chrome\\ProxyServer', + 'HKEY_CURRENT_USER\\Software\\Policies\\Google\\Chromium\\ExtensionSettings', + ]], + } + }, + BAD_POLICY_WARNING_TOOLTIP: () => { + return { + default: [], + } + }, + EXTENSION_NOT_LOADED: () => { + return { + default: ['Electron', '/path/to/extension'], + } + }, + COULD_NOT_FIND_SYSTEM_NODE: () => { + return { + default: ['16.2.1'], + } + }, + INVALID_CYPRESS_INTERNAL_ENV: () => { + return { + default: ['foo'], + } + }, + CDP_VERSION_TOO_OLD: () => { + return { + default: ['1.3', { major: 1, minor: 2 }], + older: ['1.3', { major: 0, minor: 0 }], + } + }, + CDP_COULD_NOT_CONNECT: () => { + return { + default: ['chrome', 2345, makeErr()], + } + }, + FIREFOX_COULD_NOT_CONNECT: () => { + const err = makeErr() + + return { + default: [err], + } + }, + CDP_COULD_NOT_RECONNECT: () => { + const err = makeErr() + + return { + default: [err], + } + }, + CDP_RETRYING_CONNECTION: () => { + return { + default: [1, 'chrome'], + } + }, + UNEXPECTED_BEFORE_BROWSER_LAUNCH_PROPERTIES: () => { + return { + default: [ + ['baz'], ['preferences', 'extensions', 'args'], + ], + } + }, + COULD_NOT_PARSE_ARGUMENTS: () => { + return { + default: ['spec', '1', 'spec must be a string or comma-separated list'], + } + }, + FIREFOX_MARIONETTE_FAILURE: () => { + const err = makeErr() + + return { + default: ['connection', err], + } + }, + FOLDER_NOT_WRITABLE: () => { + return { + default: ['/path/to/folder'], + } + }, + EXPERIMENTAL_SAMESITE_REMOVED: () => { + return { + default: [], + } + }, + EXPERIMENTAL_COMPONENT_TESTING_REMOVED: () => { + return { + default: [{ configFile: '/path/to/cypress.config.js' }], + } + }, + EXPERIMENTAL_SHADOW_DOM_REMOVED: () => { + return { + default: [], + } + }, + EXPERIMENTAL_NETWORK_STUBBING_REMOVED: () => { + return { + default: [], + } + }, + EXPERIMENTAL_RUN_EVENTS_REMOVED: () => { + return { + default: [], + } + }, + FIREFOX_GC_INTERVAL_REMOVED: () => { + return { + default: [], + } + }, + INCOMPATIBLE_PLUGIN_RETRIES: () => { + return { + default: ['./path/to/cypress-plugin-retries'], + } + }, + NODE_VERSION_DEPRECATION_BUNDLED: () => { + return { + default: [{ name: 'nodeVersion', value: 'bundled', 'configFile': 'cypress.json' }], + } + }, + NODE_VERSION_DEPRECATION_SYSTEM: () => { + return { + default: [{ name: 'nodeVersion', value: 'system', 'configFile': 'cypress.json' }], + } + }, + CONFIG_FILE_MIGRATION_NEEDED: () => { + return { + default: ['/path/to/projectRoot'], + } + }, + LEGACY_CONFIG_FILE: () => { + return { + default: ['cypress.json', '/path/to/projectRoot'], + } + }, + SETUP_NODE_EVENTS_DO_NOT_SUPPORT_DEV_SERVER: () => { + return { + default: ['/path/to/project/cypress.config.js'], + } + }, + CONFIG_FILE_INVALID_DEV_START_EVENT: () => { + return { + default: ['/path/to/plugins/file.js'], + } + }, + PLUGINS_RUN_EVENT_ERROR: () => { + return { + default: ['before:spec', makeErr()], + } + }, + INVALID_CONFIG_OPTION: () => { + return { + default: [['foo']], + plural: [['foo', 'bar']], + } + }, + UNSUPPORTED_BROWSER_VERSION: () => { + return { + default: [`Cypress does not support running chrome version 64. To use chrome with Cypress, install a version of chrome newer than or equal to 64.`], + } + }, + MULTIPLE_SUPPORT_FILES_FOUND: () => { + return { + default: ['spec.{ts,js}', ['support.ts', 'support.js']], + } + }, + CONFIG_FILE_INVALID_ROOT_CONFIG: () => { + return { + default: [{ name: 'specPattern', configFile: '/path/to/cypress.config.js.ts' }], + } + }, + CONFIG_FILE_INVALID_ROOT_CONFIG_E2E: () => { + return { + default: [{ name: 'baseUrl', configFile: '/path/to/cypress.config.js.ts' }], + } + }, + CONFIG_FILE_INVALID_TESTING_TYPE_CONFIG_COMPONENT: () => { + return { + default: [{ name: 'baseUrl', configFile: '/path/to/cypress.config.js.ts' }], + } + }, + CONFIG_FILE_DEV_SERVER_IS_NOT_A_FUNCTION: () => { + return { + default: ['/path/to/config.ts', {}], + } + }, + }) +}) diff --git a/packages/errors/tsconfig.json b/packages/errors/tsconfig.json new file mode 100644 index 000000000000..842a64e22c9f --- /dev/null +++ b/packages/errors/tsconfig.json @@ -0,0 +1,24 @@ +{ + "extends": "../ts/tsconfig.json", + "include": [ + "src", + "test", + ], + "exclude": [ + "script", + ], + "compilerOptions": { + "strict": true, + "allowJs": false, + "noImplicitAny": true, + "resolveJsonModule": true, + "experimentalDecorators": true, + "noImplicitReturns": false, + "noUncheckedIndexedAccess": true, + "importsNotUsedAsValues": "error", + "types": [ + "node", + "mocha" + ] + } +} \ No newline at end of file diff --git a/packages/frontend-shared/cypress/e2e/support/e2eProjectDirs.ts b/packages/frontend-shared/cypress/e2e/support/e2eProjectDirs.ts index 1bafc2ef1796..a71332ce4367 100644 --- a/packages/frontend-shared/cypress/e2e/support/e2eProjectDirs.ts +++ b/packages/frontend-shared/cypress/e2e/support/e2eProjectDirs.ts @@ -10,6 +10,7 @@ export const e2eProjectDirs = [ 'config-with-invalid-browser', 'config-with-invalid-viewport', 'config-with-js', + 'config-with-setup-function-error', 'config-with-short-timeout', 'config-with-ts', 'cookies', @@ -66,6 +67,8 @@ export const e2eProjectDirs = [ 'plugin-event-deprecated', 'plugin-extension', 'plugin-filter-browsers', + 'plugin-invalid-event-handler-error', + 'plugin-no-function-return', 'plugin-retries', 'plugin-returns-bad-config', 'plugin-returns-empty-browsers-list', @@ -75,7 +78,9 @@ export const e2eProjectDirs = [ 'plugin-validation-error', 'plugins-absolute-path', 'plugins-async-error', + 'plugins-function-sync-error', 'plugins-root-async-error', + 'plugins-root-sync-error', 'pristine', 'pristine-npm', 'pristine-pnpm', diff --git a/packages/frontend-shared/src/components/StandardModal.cy.tsx b/packages/frontend-shared/src/components/StandardModal.cy.tsx index 0da98b729541..b0c72117ef0d 100644 --- a/packages/frontend-shared/src/components/StandardModal.cy.tsx +++ b/packages/frontend-shared/src/components/StandardModal.cy.tsx @@ -145,7 +145,7 @@ describe('', { viewportWidth: 800, viewportHeight: 400 }, () => cy.get('@updateSpy').should('not.have.been.called') }) - it('doesn\'t close with click inside', () => { + it(`doesn't close with click inside`, () => { cy.contains(title).click() cy.get('@updateSpy').should('not.have.been.called') }) diff --git a/packages/launchpad/cypress/e2e/choose-a-browser.cy.ts b/packages/launchpad/cypress/e2e/choose-a-browser.cy.ts index cbc8ee8d9258..2a0be1064db3 100644 --- a/packages/launchpad/cypress/e2e/choose-a-browser.cy.ts +++ b/packages/launchpad/cypress/e2e/choose-a-browser.cy.ts @@ -31,18 +31,12 @@ describe('Choose a Browser Page', () => { cy.get('h1').should('contain', 'Choose a Browser') cy.get('[data-cy="alert-header"]').should('contain', 'Warning: Browser Not Found') cy.get('[data-cy="alert-body"]') - .should('contain', 'The specified browser was not found on your system or is not supported by Cypress: doesNotExist') + .should('contain', 'Browser: doesNotExist was not found on your system or is not supported by Cypress.') cy.get('[data-cy="alert-body"]').within(() => { cy.validateExternalLink({ - name: 'use a custom browser', href: 'https://on.cypress.io/customize-browsers', }) - - cy.validateExternalLink({ - name: 'how to troubleshoot launching browsers', - href: 'https://on.cypress.io/troubleshooting-launching-browsers', - }) }) // Ensure warning can be dismissed @@ -59,9 +53,9 @@ describe('Choose a Browser Page', () => { cy.get('[data-cy="alert-header"]').should('contain', 'Warning: Browser Not Found') cy.get('[data-cy="alert-body"]') - .should('contain', 'We could not identify a known browser at the path you specified: /path/does/not/exist') + .should('contain', 'We could not identify a known browser at the path you provided: /path/does/not/exist') + .should('contain', 'spawn /path/does/not/exist ENOENT') .validateExternalLink({ - name: 'how to troubleshoot launching browsers', href: 'https://on.cypress.io/troubleshooting-launching-browsers', }) diff --git a/packages/launchpad/cypress/e2e/error-handling.cy.ts b/packages/launchpad/cypress/e2e/error-handling.cy.ts index 84ae9ea4b75d..d27101e6750a 100644 --- a/packages/launchpad/cypress/e2e/error-handling.cy.ts +++ b/packages/launchpad/cypress/e2e/error-handling.cy.ts @@ -1,5 +1,5 @@ describe('Error handling', () => { - it('it handles a plugin error', () => { + it('it handles a config error', () => { cy.scaffoldProject('unify-plugin-errors') cy.openProject('unify-plugin-errors') cy.loginUser() @@ -10,8 +10,7 @@ describe('Error handling', () => { cy.get('body') .should('contain.text', 'Please confirm that everything looks correct in your cypress.config.js file.') - .should('contain.text', 'Error Loading Config') - .and('contain.text', 'The function exported by the plugins file threw an error') + .and('contain.text', 'threw an error from') cy.get('[data-cy="collapsible-header"]') .should('have.attr', 'aria-expanded', 'true') diff --git a/packages/net-stubbing/lib/server/middleware/error.ts b/packages/net-stubbing/lib/server/middleware/error.ts index 40c6394484e3..a46bda5fdfe3 100644 --- a/packages/net-stubbing/lib/server/middleware/error.ts +++ b/packages/net-stubbing/lib/server/middleware/error.ts @@ -3,7 +3,7 @@ import Debug from 'debug' import type { ErrorMiddleware } from '@packages/proxy' import type { CyHttpMessages } from '../../types' import _ from 'lodash' -import errors from '@packages/server/lib/errors' +import * as errors from '@packages/server/lib/errors' const debug = Debug('cypress:net-stubbing:server:intercept-error') @@ -22,7 +22,7 @@ export const InterceptError: ErrorMiddleware = async function () { await request.handleSubscriptions({ eventName: 'network:error', data: { - error: errors.clone(this.error), + error: errors.cloneErr(this.error), }, mergeChanges: _.noop, }) diff --git a/packages/net-stubbing/test/unit/route-matching-spec.ts b/packages/net-stubbing/test/unit/route-matching-spec.ts index 77cc7ecdd7c6..3c78e3934fa3 100644 --- a/packages/net-stubbing/test/unit/route-matching-spec.ts +++ b/packages/net-stubbing/test/unit/route-matching-spec.ts @@ -90,7 +90,7 @@ describe('intercept-request', function () { }) }) - it('doesn\'t match on a partial match', function () { + it(`doesn't match on a partial match`, function () { tryMatch({ headers: { authorization: 'basic Zm9vOmJhcg==', diff --git a/packages/network/lib/client-certificates.ts b/packages/network/lib/client-certificates.ts index f8003e79c202..ec6fcfac096d 100644 --- a/packages/network/lib/client-certificates.ts +++ b/packages/network/lib/client-certificates.ts @@ -4,6 +4,7 @@ import minimatch from 'minimatch' import Forge from 'node-forge' import fs from 'fs-extra' import { clientCertificateStore } from './agent' + const { pki, asn1, pkcs12, util } = Forge const debug = debugModule('cypress:network:client-certificates') @@ -271,7 +272,7 @@ export function loadClientCertificateConfig (config) { if (passphrase) { if (!pki.decryptRsaPrivateKey(pemKeyRaw, passphrase)) { throw new Error( - 'Cannot decrypt PEM key with supplied passphrase (check the passphrase file content and that it doesn\'t have unexpected whitespace at the end)', + `Cannot decrypt PEM key with supplied passphrase (check the passphrase file content and that it doesn't have unexpected whitespace at the end)`, ) } } else { diff --git a/packages/network/test/unit/client_certificates_spec.ts b/packages/network/test/unit/client_certificates_spec.ts index a942f0f600e5..2d0fd6e7a8d7 100644 --- a/packages/network/test/unit/client_certificates_spec.ts +++ b/packages/network/test/unit/client_certificates_spec.ts @@ -554,7 +554,7 @@ describe('lib/client-certificates', () => { } expect(act).to.throw( - 'Cannot decrypt PEM key with supplied passphrase (check the passphrase file content and that it doesn\'t have unexpected whitespace at the end)', + `Cannot decrypt PEM key with supplied passphrase (check the passphrase file content and that it doesn't have unexpected whitespace at the end)`, ) }) diff --git a/packages/proxy/lib/http/error-middleware.ts b/packages/proxy/lib/http/error-middleware.ts index 43de4c39bff1..aed898b6fdbe 100644 --- a/packages/proxy/lib/http/error-middleware.ts +++ b/packages/proxy/lib/http/error-middleware.ts @@ -1,10 +1,10 @@ import debugModule from 'debug' +import * as errors from '@packages/server/lib/errors' + import type { HttpMiddleware } from '.' import type { Readable } from 'stream' import { InterceptError } from '@packages/net-stubbing' import type { Request } from '@cypress/request' -import errors from '@packages/server/lib/errors' - const debug = debugModule('cypress:proxy:http:error-middleware') export type ErrorMiddleware = HttpMiddleware<{ @@ -27,7 +27,7 @@ const SendToDriver: ErrorMiddleware = function () { if (this.req.browserPreRequest) { this.socket.toDriver('request:event', 'request:error', { requestId: this.req.browserPreRequest.requestId, - error: errors.clone(this.error), + error: errors.cloneErr(this.error), }) } diff --git a/packages/proxy/test/unit/http/response-middleware.spec.ts b/packages/proxy/test/unit/http/response-middleware.spec.ts index 320180edf42f..5223e0063c59 100644 --- a/packages/proxy/test/unit/http/response-middleware.spec.ts +++ b/packages/proxy/test/unit/http/response-middleware.spec.ts @@ -48,7 +48,7 @@ describe('http/response-middleware', function () { prepareContext() }) - it('doesn\'t do anything', function () { + it(`doesn't do anything`, function () { return testMiddleware([MaybeStripDocumentDomainFeaturePolicy], ctx) .then(() => { expect(ctx.res.set).not.to.be.called @@ -62,7 +62,7 @@ describe('http/response-middleware', function () { prepareContext() }) - it('doesn\'t do anything', function () { + it(`doesn't do anything`, function () { return testMiddleware([MaybeStripDocumentDomainFeaturePolicy], ctx) .then(() => { expect(ctx.res.set).not.to.be.called diff --git a/packages/runner-ct/package.json b/packages/runner-ct/package.json index 5e5c0db05017..4210f2a842ca 100644 --- a/packages/runner-ct/package.json +++ b/packages/runner-ct/package.json @@ -26,7 +26,6 @@ "@types/http-proxy": "1.17.4", "@types/node": "14.14.31", "@types/sockjs-client": "1.1.0", - "ansi-to-html": "0.6.14", "babel-loader": "8.1.0", "bluebird": "3.5.3", "cash-dom": "^8.1.0", diff --git a/packages/runner/package.json b/packages/runner/package.json index a3575aff652b..6694ddbcec6e 100644 --- a/packages/runner/package.json +++ b/packages/runner/package.json @@ -33,7 +33,6 @@ "@packages/web-config": "0.0.0-development", "@reach/dialog": "0.10.5", "@reach/visually-hidden": "0.10.4", - "ansi-to-html": "0.6.14", "babel-plugin-prismjs": "1.0.2", "bluebird": "3.5.3", "chai": "4.2.0", diff --git a/packages/server/__snapshots__/args_spec.js b/packages/server/__snapshots__/args_spec.js index d30933eb14df..a75c37a22813 100644 --- a/packages/server/__snapshots__/args_spec.js +++ b/packages/server/__snapshots__/args_spec.js @@ -1,5 +1,5 @@ exports['invalid env error'] = ` -Cypress encountered an error while parsing the argument env +Cypress encountered an error while parsing the argument: --env You passed: nonono @@ -7,7 +7,7 @@ The error was: Cannot parse as valid JSON ` exports['invalid reporter options error'] = ` -Cypress encountered an error while parsing the argument reporterOptions +Cypress encountered an error while parsing the argument: --reporterOptions You passed: abc @@ -15,7 +15,7 @@ The error was: Cannot parse as valid JSON ` exports['invalid config error'] = ` -Cypress encountered an error while parsing the argument config +Cypress encountered an error while parsing the argument: --config You passed: xyz @@ -23,9 +23,9 @@ The error was: Cannot parse as valid JSON ` exports['invalid spec error'] = ` -Cypress encountered an error while parsing the argument spec +Cypress encountered an error while parsing the argument: --spec -You passed: [object Object] +You passed: {} The error was: spec must be a string or comma-separated list ` diff --git a/packages/server/__snapshots__/browsers_spec.js b/packages/server/__snapshots__/browsers_spec.js index e6b5e3f33340..4d9e8283e385 100644 --- a/packages/server/__snapshots__/browsers_spec.js +++ b/packages/server/__snapshots__/browsers_spec.js @@ -1,43 +1,45 @@ exports['lib/browsers/index .ensureAndGetByNameOrPath throws when no browser can be found 1'] = ` -The specified browser was not found on your system or is not supported by Cypress: \`browserNotGonnaBeFound\` +Can't run because you've entered an invalid browser name. + +Browser: browserNotGonnaBeFound was not found on your system or is not supported by Cypress. Cypress supports the following browsers: -- chrome -- chromium -- edge -- electron -- firefox + - electron + - chrome + - chromium + - chrome:canary + - edge + - firefox -You can also [use a custom browser](https://on.cypress.io/customize-browsers). +You can also use a custom browser: https://on.cypress.io/customize-browsers Available browsers found on your system are: -- chrome -- firefox -- electron - -Read more about [how to troubleshoot launching browsers](https://on.cypress.io/troubleshooting-launching-browsers). + - chrome + - firefox + - electron ` exports['lib/browsers/index .ensureAndGetByNameOrPath throws a special error when canary is passed 1'] = ` -The specified browser was not found on your system or is not supported by Cypress: \`canary\` +Can't run because you've entered an invalid browser name. + +Browser: canary was not found on your system or is not supported by Cypress. Cypress supports the following browsers: -- chrome -- chromium -- edge -- electron -- firefox + - electron + - chrome + - chromium + - chrome:canary + - edge + - firefox -You can also [use a custom browser](https://on.cypress.io/customize-browsers). +You can also use a custom browser: https://on.cypress.io/customize-browsers Available browsers found on your system are: -- chrome -- chrome:canary -- firefox - -Read more about [how to troubleshoot launching browsers](https://on.cypress.io/troubleshooting-launching-browsers). + - chrome + - chrome:canary + - firefox -Note: In Cypress version 4.0.0, Canary must be launched as \`chrome:canary\`, not \`canary\`. +Note: In Cypress version 4.0.0, Canary must be launched as chrome:canary, not canary. See https://on.cypress.io/migration-guide for more information on breaking changes in 4.0.0. ` diff --git a/packages/server/__snapshots__/cypress_spec.js b/packages/server/__snapshots__/cypress_spec.js index 7c4779988bf1..1fb15ac8d9f2 100644 --- a/packages/server/__snapshots__/cypress_spec.js +++ b/packages/server/__snapshots__/cypress_spec.js @@ -58,29 +58,29 @@ In order to use either of these features a ciBuildId must be determined. The ciBuildId is automatically detected if you are running Cypress in any of the these CI providers: -- appveyor -- azure -- awsCodeBuild -- bamboo -- bitbucket -- buildkite -- circle -- codeshipBasic -- codeshipPro -- concourse -- codeFresh -- drone -- githubActions -- gitlab -- goCD -- googleCloud -- jenkins -- semaphore -- shippable -- teamfoundation -- travis -- netlify -- layerci + - appveyor + - azure + - awsCodeBuild + - bamboo + - bitbucket + - buildkite + - circle + - codeshipBasic + - codeshipPro + - concourse + - codeFresh + - drone + - githubActions + - gitlab + - goCD + - googleCloud + - jenkins + - semaphore + - shippable + - teamfoundation + - travis + - netlify + - layerci Because the ciBuildId could not be auto-detected you must pass the --ci-build-id flag manually. @@ -96,29 +96,29 @@ In order to use either of these features a ciBuildId must be determined. The ciBuildId is automatically detected if you are running Cypress in any of the these CI providers: -- appveyor -- azure -- awsCodeBuild -- bamboo -- bitbucket -- buildkite -- circle -- codeshipBasic -- codeshipPro -- concourse -- codeFresh -- drone -- githubActions -- gitlab -- goCD -- googleCloud -- jenkins -- semaphore -- shippable -- teamfoundation -- travis -- netlify -- layerci + - appveyor + - azure + - awsCodeBuild + - bamboo + - bitbucket + - buildkite + - circle + - codeshipBasic + - codeshipPro + - concourse + - codeFresh + - drone + - githubActions + - gitlab + - goCD + - googleCloud + - jenkins + - semaphore + - shippable + - teamfoundation + - travis + - netlify + - layerci Because the ciBuildId could not be auto-detected you must pass the --ci-build-id flag manually. @@ -135,29 +135,29 @@ In order to use either of these features a ciBuildId must be determined. The ciBuildId is automatically detected if you are running Cypress in any of the these CI providers: -- appveyor -- azure -- awsCodeBuild -- bamboo -- bitbucket -- buildkite -- circle -- codeshipBasic -- codeshipPro -- concourse -- codeFresh -- drone -- githubActions -- gitlab -- goCD -- googleCloud -- jenkins -- semaphore -- shippable -- teamfoundation -- travis -- netlify -- layerci + - appveyor + - azure + - awsCodeBuild + - bamboo + - bitbucket + - buildkite + - circle + - codeshipBasic + - codeshipPro + - concourse + - codeFresh + - drone + - githubActions + - gitlab + - goCD + - googleCloud + - jenkins + - semaphore + - shippable + - teamfoundation + - travis + - netlify + - layerci Because the ciBuildId could not be auto-detected you must pass the --ci-build-id flag manually. @@ -192,11 +192,11 @@ The existing run is: https://dashboard.cypress.io/runs/12345 In order to run in parallel mode each machine must send identical environment parameters such as: -- specs -- osName -- osVersion -- browserName -- browserVersion (major) + - specs + - osName + - osVersion + - browserName + - browserVersion (major) This machine sent the following parameters: @@ -278,7 +278,7 @@ https://on.cypress.io/record-params-without-recording ` exports['could not parse config error'] = ` -Cypress encountered an error while parsing the argument config +Cypress encountered an error while parsing the argument: --config You passed: xyz @@ -286,7 +286,7 @@ The error was: Cannot parse as valid JSON ` exports['could not parse env error'] = ` -Cypress encountered an error while parsing the argument env +Cypress encountered an error while parsing the argument: --env You passed: a123 @@ -294,7 +294,7 @@ The error was: Cannot parse as valid JSON ` exports['could not parse reporter options error'] = ` -Cypress encountered an error while parsing the argument reporterOptions +Cypress encountered an error while parsing the argument: --reporterOptions You passed: nonono @@ -302,7 +302,10 @@ The error was: Cannot parse as valid JSON ` exports['INVALID_CONFIG_OPTION'] = ` -\`test\` is not a valid configuration option,\`foo\` is not a valid configuration option +The following configuration options are invalid: + + - test + - foo https://on.cypress.io/configuration diff --git a/packages/server/__snapshots__/errors_spec.ts.js b/packages/server/__snapshots__/errors_spec.ts.js new file mode 100644 index 000000000000..c809a4d34bea --- /dev/null +++ b/packages/server/__snapshots__/errors_spec.ts.js @@ -0,0 +1,4 @@ +exports['tags and name only'] = ` +The --tag flag you passed was: nightly,staging +The --name flag you passed was: my tests +` diff --git a/packages/server/lib/api.js b/packages/server/lib/api.js index ff1b7eaa6ce7..e75f9a5df594 100644 --- a/packages/server/lib/api.js +++ b/packages/server/lib/api.js @@ -8,7 +8,6 @@ const humanInterval = require('human-interval') const { agent } = require('@packages/network') const pkg = require('@packages/root') const machineId = require('./util/machine_id') -const humanTime = require('./util/human_time') const errors = require('./errors') const { apiRoutes } = require('./util/routes') @@ -116,7 +115,7 @@ const retryWithBackoff = (fn) => { errors.warning( 'DASHBOARD_API_RESPONSE_FAILED_RETRYING', { - delay: humanTime.long(delay, false), + delay, tries: DELAYS.length - retryIndex, response: err, }, diff --git a/packages/server/lib/browsers/browser-cri-client.ts b/packages/server/lib/browsers/browser-cri-client.ts index b64aa496a339..900a03953681 100644 --- a/packages/server/lib/browsers/browser-cri-client.ts +++ b/packages/server/lib/browsers/browser-cri-client.ts @@ -1,7 +1,7 @@ import CRI from 'chrome-remote-interface' import Debug from 'debug' import { _connectAsync, _getDelayMsForRetry } from './protocol' -import errors from '../errors' +import * as errors from '../errors' import { create, CRIWrapper } from './cri-client' const HOST = '127.0.0.1' @@ -36,7 +36,7 @@ const ensureLiveBrowser = async (port: number, browserName: string) => { await _connectAsync(connectOpts) } catch (err) { debug('failed to connect to CDP %o', { connectOpts, err }) - errors.throw('CDP_COULD_NOT_CONNECT', port, err, browserName) + errors.throwErr('CDP_COULD_NOT_CONNECT', browserName, port, err) } } @@ -94,7 +94,7 @@ export class BrowserCriClient { const minimum = getMajorMinorVersion(protocolVersion) if (!isVersionGte(actualVersion, minimum)) { - errors.throw('CDP_VERSION_TOO_OLD', protocolVersion, actualVersion) + errors.throwErr('CDP_VERSION_TOO_OLD', protocolVersion, actualVersion) } } diff --git a/packages/server/lib/browsers/cri-client.ts b/packages/server/lib/browsers/cri-client.ts index 740aac719efa..0310c08b6537 100644 --- a/packages/server/lib/browsers/cri-client.ts +++ b/packages/server/lib/browsers/cri-client.ts @@ -1,7 +1,7 @@ import debugModule from 'debug' import _ from 'lodash' import CRI from 'chrome-remote-interface' -import errors from '../errors' +import * as errors from '../errors' const debug = debugModule('cypress:server:browsers:cri-client') // debug using cypress-verbose:server:browsers:cri-client:send:* diff --git a/packages/server/lib/browsers/firefox.ts b/packages/server/lib/browsers/firefox.ts index 3e69f3a4d65e..31e686ea29ee 100644 --- a/packages/server/lib/browsers/firefox.ts +++ b/packages/server/lib/browsers/firefox.ts @@ -7,6 +7,7 @@ import path from 'path' import urlUtil from 'url' import { launch, LaunchedBrowser } from '@packages/launcher/lib/browsers' import FirefoxProfile from 'firefox-profile' +import * as errors from '../errors' import firefoxUtil from './firefox-util' import utils from './utils' import * as launcherDebug from '@packages/launcher/lib/log' @@ -19,8 +20,6 @@ import { getRemoteDebuggingPort } from './protocol' import type { BrowserCriClient } from './browser-cri-client' import type { Automation } from '../automation' -const errors = require('../errors') - const debug = Debug('cypress:server:browsers:firefox') // used to prevent the download prompt for the specified file types. @@ -554,7 +553,7 @@ export async function open (browser: Browser, url, options: any = {}, automation originalBrowserKill.apply(browserInstance, args) } } catch (err) { - errors.throw('FIREFOX_COULD_NOT_CONNECT', err) + errors.throwErr('FIREFOX_COULD_NOT_CONNECT', err) } return browserInstance diff --git a/packages/server/lib/browsers/index.js b/packages/server/lib/browsers/index.js index 7fe6e7b47cd3..5870870cb11d 100644 --- a/packages/server/lib/browsers/index.js +++ b/packages/server/lib/browsers/index.js @@ -94,6 +94,8 @@ module.exports = { close: kill, + formatBrowsersToOptions: utils.formatBrowsersToOptions, + _setInstance (_instance) { // for testing instance = _instance diff --git a/packages/server/lib/browsers/utils.ts b/packages/server/lib/browsers/utils.ts index 5952b2b5e6df..bcbbe0868256 100644 --- a/packages/server/lib/browsers/utils.ts +++ b/packages/server/lib/browsers/utils.ts @@ -2,10 +2,10 @@ import Bluebird from 'bluebird' import _ from 'lodash' import type { FoundBrowser } from '@packages/types' -// @ts-ignore -import errors from '../errors' +import * as errors from '../errors' // @ts-ignore import plugins from '../plugins' +import { getError } from '@packages/errors' const path = require('path') const debug = require('debug')('cypress:server:browsers:utils') @@ -139,7 +139,7 @@ function extendLaunchOptionsFromPlugins (launchOptions, pluginConfigResult, opti // interface and we need to warn them // TODO: remove this logic in >= v5.0.0 if (pluginConfigResult[0]) { - options.onWarning(errors.get( + options.onWarning(getError( 'DEPRECATED_BEFORE_BROWSER_LAUNCH_ARGS', )) @@ -160,7 +160,7 @@ function extendLaunchOptionsFromPlugins (launchOptions, pluginConfigResult, opti .value() if (unexpectedProperties.length) { - errors.throw('UNEXPECTED_BEFORE_BROWSER_LAUNCH_PROPERTIES', unexpectedProperties, KNOWN_LAUNCH_OPTION_PROPERTIES) + errors.throwErr('UNEXPECTED_BEFORE_BROWSER_LAUNCH_PROPERTIES', unexpectedProperties, KNOWN_LAUNCH_OPTION_PROPERTIES) } } @@ -282,7 +282,7 @@ function ensureAndGetByNameOrPath (nameOrPath: string, returnAll = false, browse return browser }).catch((err) => { - errors.throw('BROWSER_NOT_FOUND_BY_PATH', nameOrPath, err.message) + errors.throwErr('BROWSER_NOT_FOUND_BY_PATH', nameOrPath, err.message) }) } @@ -301,13 +301,12 @@ const formatBrowsersToOptions = (browsers) => { }) } -const throwBrowserNotFound = (browserName, browsers: FoundBrowser[] = []) => { - const names = `- ${formatBrowsersToOptions(browsers).join('\n- ')}` - - return errors.throw('BROWSER_NOT_FOUND_BY_NAME', browserName, names) +const throwBrowserNotFound = function (browserName, browsers: FoundBrowser[] = []) { + return errors.throwErr('BROWSER_NOT_FOUND_BY_NAME', browserName, formatBrowsersToOptions(browsers)) } export = { + extendLaunchOptionsFromPlugins, executeBeforeBrowserLaunch, @@ -336,6 +335,8 @@ export = { getBrowsers, + formatBrowsersToOptions, + throwBrowserNotFound, writeExtension (browser, isTextTerminal, proxyUrl, socketIoRoute) { diff --git a/packages/server/lib/config.ts b/packages/server/lib/config.ts index 02dcc23becd3..fa11863c99e7 100644 --- a/packages/server/lib/config.ts +++ b/packages/server/lib/config.ts @@ -1,22 +1,23 @@ +import Bluebird from 'bluebird' +import Debug from 'debug' import _ from 'lodash' import path from 'path' -import Bluebird from 'bluebird' import deepDiff from 'return-deep-diff' import type { ResolvedFromConfig, ResolvedConfigurationOptionSource, AllModeOptions, FullConfig } from '@packages/types' import configUtils from '@packages/config' - -import errors from './errors' +import * as errors from './errors' +import { getProcessEnvVars, CYPRESS_SPECIAL_ENV_VARS } from './util/config' import { fs } from './util/fs' import keys from './util/keys' import origin from './util/origin' -import Debug from 'debug' import pathHelpers from './util/path_helpers' -const debug = Debug('cypress:server:config') +import type { ConfigValidationError } from '@packages/errors' -import { getProcessEnvVars, CYPRESS_SPECIAL_ENV_VARS } from './util/config' import { getCtx } from './makeDataContext' +const debug = Debug('cypress:server:config') + const folders = _(configUtils.options).filter({ isFolder: true }).map('name').value() const convertRelativeToAbsolutePaths = (projectRoot, obj) => { @@ -152,7 +153,7 @@ export function mergeDefaults ( config.cypressEnv = process.env.CYPRESS_INTERNAL_ENV debug('using CYPRESS_INTERNAL_ENV %s', config.cypressEnv) if (!isValidCypressInternalEnvValue(config.cypressEnv)) { - throw errors.throw('INVALID_CYPRESS_INTERNAL_ENV', config.cypressEnv) + throw errors.throwErr('INVALID_CYPRESS_INTERNAL_ENV', config.cypressEnv) } delete config.envFile @@ -175,8 +176,13 @@ export function mergeDefaults ( // validate config again here so that we catch configuration errors coming // from the CLI overrides or env var overrides - configUtils.validate(_.omit(config, 'browsers'), (errMsg) => { - throw errors.throw('CONFIG_VALIDATION_ERROR', errMsg) + configUtils.validate(_.omit(config, 'browsers'), (validationResult: ConfigValidationError | string) => { + // return errors.throwErr('CONFIG_VALIDATION_ERROR', errMsg) + if (_.isString(validationResult)) { + return errors.throwErr('CONFIG_VALIDATION_MSG_ERROR', null, null, validationResult) + } + + return errors.throwErr('CONFIG_VALIDATION_ERROR', null, null, validationResult) }) config = setAbsolutePaths(config) @@ -228,14 +234,19 @@ export function updateWithPluginValues (cfg, overrides) { // make sure every option returned from the plugins file // passes our validation functions - configUtils.validate(overrides, (errMsg) => { - const configFile = getCtx().lifecycleManager.configFile + configUtils.validate(overrides, (validationResult: ConfigValidationError | string) => { + let configFile = getCtx().lifecycleManager.configFile - if (configFile) { - return errors.throw('PLUGINS_CONFIG_VALIDATION_ERROR', configFile, errMsg) + if (configFile === false) { + configFile = '--config file set to "false" via CLI--' } - return errors.throw('CONFIG_VALIDATION_ERROR', errMsg) + if (_.isString(validationResult)) { + return errors.throwErr('CONFIG_VALIDATION_MSG_ERROR', 'configFile', configFile, validationResult) + } + + return errors.throwErr('CONFIG_VALIDATION_ERROR', 'configFile', configFile, validationResult) + // return errors.throwErr('CONFIG_VALIDATION_ERROR', 'pluginsFile', relativePluginsPath, errMsg) }) let originalResolvedBrowsers = cfg && cfg.resolved && cfg.resolved.browsers && _.cloneDeep(cfg.resolved.browsers) @@ -360,13 +371,11 @@ export async function setSupportFileAndFolder (obj, defaults) { const supportFilesByGlob = await ctx.file.getFilesByGlob(obj.projectRoot, obj.supportFile, { absolute: false }) if (supportFilesByGlob.length > 1) { - return errors.throw('MULTIPLE_SUPPORT_FILES_FOUND', obj.supportFile, supportFilesByGlob.join(', ')) + return errors.throwErr('MULTIPLE_SUPPORT_FILES_FOUND', obj.supportFile, supportFilesByGlob) } if (supportFilesByGlob.length === 0) { - const configFile = obj.configFile || defaults.configFile - - return errors.throw('SUPPORT_FILE_NOT_FOUND', path.resolve(obj.projectRoot, obj.supportFile), configFile) + return errors.throwErr('SUPPORT_FILE_NOT_FOUND', path.resolve(obj.projectRoot, obj.supportFile)) } // TODO move this logic to find support file into util/path_helpers @@ -399,7 +408,7 @@ export async function setSupportFileAndFolder (obj, defaults) { return fs.pathExists(obj.supportFile) .then((found) => { if (!found) { - errors.throw('SUPPORT_FILE_NOT_FOUND', obj.supportFile, obj.configFile || defaults.configFile) + errors.throwErr('SUPPORT_FILE_NOT_FOUND', obj.supportFile) } return debug('switching to found file %s', obj.supportFile) @@ -413,9 +422,7 @@ export async function setSupportFileAndFolder (obj, defaults) { }) .then((result) => { if (result === null) { - const configFile = obj.configFile || defaults.configFile - - return errors.throw('SUPPORT_FILE_NOT_FOUND', path.resolve(obj.projectRoot, sf), configFile) + return errors.throwErr('SUPPORT_FILE_NOT_FOUND', path.resolve(obj.projectRoot, sf)) } debug('setting support file to %o', { result }) diff --git a/packages/server/lib/cwd.js b/packages/server/lib/cwd.js index 2358f74e5701..368edaeef068 100644 --- a/packages/server/lib/cwd.js +++ b/packages/server/lib/cwd.js @@ -1,27 +1,7 @@ const path = require('path') -// helper for resolving to the current working directory -// since electron does not play nice with process.cwd() -// this function should always return path.dirname('package.json') -const appPath = (function () { - // if lib is our basename then we haven't - // been concatted or moved and we need to - // walk up one folder to access our app path - if (path.basename(__dirname) === 'lib') { - return path.join(__dirname, '..') - } - - // we are already in the app path - return __dirname -})() - -// after we figure out our appPath -// if the process.cwd() isnt set to that -// then change it -if (process.cwd() !== appPath) { - process.chdir(appPath) -} +const serverPath = path.join(__dirname, '..') module.exports = (...args) => { - return path.join(appPath, ...args) + return path.join(serverPath, ...args) } diff --git a/packages/server/lib/cypress.js b/packages/server/lib/cypress.js index b0e1e1e62a1e..7147ee36e34a 100644 --- a/packages/server/lib/cypress.js +++ b/packages/server/lib/cypress.js @@ -13,7 +13,6 @@ const Promise = require('bluebird') const debug = require('debug')('cypress:server:cypress') const { getPublicConfigKeys } = require('@packages/config') const argsUtils = require('./util/args') -const chalk = require('chalk') const { openProject } = require('../lib/open_project') const warning = (code, args) => { @@ -108,7 +107,10 @@ module.exports = { debug('electron open arguments %o', args) - return cypressElectron.open('.', args, fn) + // const mainEntryFile = require.main.filename + const serverMain = require('./cwd')() + + return cypressElectron.open(serverMain, args, fn) }) }) }, @@ -239,7 +241,7 @@ module.exports = { if (isCanceled) { // eslint-disable-next-line no-console - console.log(chalk.magenta('\n Exiting with non-zero exit code because the run was canceled.')) + console.log(require('chalk').magenta('\n Exiting with non-zero exit code because the run was canceled.')) return 1 } diff --git a/packages/server/lib/environment.js b/packages/server/lib/environment.js index 183c0dab7514..4a20b9df2443 100644 --- a/packages/server/lib/environment.js +++ b/packages/server/lib/environment.js @@ -2,10 +2,6 @@ require('./util/fs') const os = require('os') -// NOTE: by loading "./cwd" we are changing the current working directory -// to the "packages/server" folder -require('./cwd') - const Promise = require('bluebird') const debug = require('debug')('cypress:server') diff --git a/packages/server/lib/errors.js b/packages/server/lib/errors-old.js similarity index 100% rename from packages/server/lib/errors.js rename to packages/server/lib/errors-old.js diff --git a/packages/server/lib/errors.ts b/packages/server/lib/errors.ts new file mode 100644 index 000000000000..b1efeef93d5f --- /dev/null +++ b/packages/server/lib/errors.ts @@ -0,0 +1,30 @@ +import Bluebird from 'bluebird' +import errors from '@packages/errors' +import exception from './exception' + +const isProduction = () => { + return process.env['CYPRESS_INTERNAL_ENV'] === 'production' +} + +export const logException = Bluebird.method(function (this: any, err) { + // TODO: remove context here + if (this.log(err) && isProduction()) { + // log this exception since + // its not a known error + return exception + .create(err) + .catch(() => {}) + } +}) + +export const get = errors.get + +export const log = errors.log + +export const warning = errors.warning + +export const throwErr = errors.throwErr + +export const cloneErr = errors.cloneErr + +export const stripAnsi = errors.stripAnsi diff --git a/packages/server/lib/fixture.js b/packages/server/lib/fixture.js index 32d13557c608..c49c39c2c56f 100644 --- a/packages/server/lib/fixture.js +++ b/packages/server/lib/fixture.js @@ -54,12 +54,13 @@ module.exports = { return glob(pattern, { nosort: true, nodir: true, - }).bind(this) + }) + .bind(this) .then(function (matches) { if (matches.length === 0) { const relativePath = path.relative('.', p) - errors.throw('FIXTURE_NOT_FOUND', relativePath, extensions) + errors.throwErr('FIXTURE_NOT_FOUND', relativePath, extensions) } debug('fixture matches found, using the first', matches) diff --git a/packages/server/lib/gui/events.ts b/packages/server/lib/gui/events.ts index cb8a91d2a62b..906ca37ab7af 100644 --- a/packages/server/lib/gui/events.ts +++ b/packages/server/lib/gui/events.ts @@ -74,13 +74,13 @@ const handleEvent = function (options, bus, event, id, type, arg) { // } // const onError = (err) => { - // return bus.emit('project:error', errors.clone(err, { html: true })) + // return bus.emit('project:error', errors.cloneErr(err, { html: true })) // } // const onWarning = function (warning) { // warning.message = stripAnsi(warning.message) - // return bus.emit('project:warning', errors.clone(warning, { html: true })) + // return bus.emit('project:warning', errors.cloneErr(warning, { html: true })) // } // return browsers.getAllBrowsersWith(options.browser) diff --git a/packages/server/lib/konfig.js b/packages/server/lib/konfig.js index 12296948163f..d50983eb5fe3 100644 --- a/packages/server/lib/konfig.js +++ b/packages/server/lib/konfig.js @@ -1,7 +1,11 @@ +const path = require('path') + require('./environment') const konfig = require('konfig') +const pathToConfigDir = path.resolve(__dirname, '..', 'config') + const getConfig = function () { const { env } = process @@ -14,7 +18,7 @@ const getConfig = function () { env.NODE_ENV = env.CYPRESS_KONFIG_ENV || env.CYPRESS_INTERNAL_ENV // get the config values - const config = konfig().app + const config = konfig({ path: pathToConfigDir }).app // restore NODE_ENV to previous state if (previousNodeEnvExisted) { diff --git a/packages/server/lib/makeDataContext.ts b/packages/server/lib/makeDataContext.ts index aefb43013c43..634befa312f4 100644 --- a/packages/server/lib/makeDataContext.ts +++ b/packages/server/lib/makeDataContext.ts @@ -19,7 +19,6 @@ import user from './user' import * as config from './config' import { openProject } from './open_project' import cache from './cache' -import errors from './errors' import findSystemNode from './util/find_system_node' import { graphqlSchema } from '@packages/graphql/src/schema' import { openExternal } from '@packages/server/lib/gui/links' @@ -55,11 +54,6 @@ export function makeDataContext (options: MakeDataContextOptions): DataContext { return openProject.projectBase?.sendFocusBrowserMessage() }, }, - errorApi: { - error: errors.get, - message: errors.getMsgByType, - warning: errors.warning, - }, configApi: { getServerPluginHandlers: plugins.getServerPluginHandlers, allowedConfig: configUtils.allowed, diff --git a/packages/server/lib/modes/record.js b/packages/server/lib/modes/record.js index a79d53cba0c4..30d19ce7f24d 100644 --- a/packages/server/lib/modes/record.js +++ b/packages/server/lib/modes/record.js @@ -65,7 +65,7 @@ const throwDashboardCannotProceed = ({ parallel, ciBuildId, group, err }) => { const throwIfIndeterminateCiBuildId = (ciBuildId, parallel, group) => { if ((!ciBuildId && !ciProvider.provider()) && (parallel || group)) { - errors.throw( + errors.throwErr( 'INDETERMINATE_CI_BUILD_ID', { group, @@ -78,7 +78,7 @@ const throwIfIndeterminateCiBuildId = (ciBuildId, parallel, group) => { const throwIfRecordParamsWithoutRecording = (record, ciBuildId, parallel, group, tag) => { if (!record && _.some([ciBuildId, parallel, group, tag])) { - errors.throw('RECORD_PARAMS_WITHOUT_RECORDING', { + errors.throwErr('RECORD_PARAMS_WITHOUT_RECORDING', { ciBuildId, tag, group, @@ -91,13 +91,13 @@ const throwIfIncorrectCiBuildIdUsage = (ciBuildId, parallel, group) => { // we've been given an explicit ciBuildId // but no parallel or group flag if (ciBuildId && (!parallel && !group)) { - errors.throw('INCORRECT_CI_BUILD_ID_USAGE', { ciBuildId }) + errors.throwErr('INCORRECT_CI_BUILD_ID_USAGE', { ciBuildId }) } } const throwIfNoProjectId = (projectId, configFile) => { if (!projectId) { - errors.throw('CANNOT_RECORD_NO_PROJECT_ID', configFile) + errors.throwErr('CANNOT_RECORD_NO_PROJECT_ID', configFile) } } @@ -245,14 +245,6 @@ const getCommitFromGitOrCi = (git) => { }) } -const usedTestsMessage = (limit, phrase) => { - if (_.isFinite(limit)) { - return `The limit is ${chalk.blue(limit)} ${phrase} results.` - } - - return '' -} - const billingLink = (orgId) => { if (orgId) { return `https://on.cypress.io/dashboard/organizations/${orgId}/billing` @@ -289,7 +281,7 @@ const createRun = Promise.method((options = {}) => { } // else throw - errors.throw('RECORD_KEY_MISSING') + errors.throwErr('RECORD_KEY_MISSING') } // go back to being a string @@ -338,13 +330,15 @@ const createRun = Promise.method((options = {}) => { switch (warning.code) { case 'FREE_PLAN_IN_GRACE_PERIOD_EXCEEDS_MONTHLY_PRIVATE_TESTS': return errors.warning('FREE_PLAN_IN_GRACE_PERIOD_EXCEEDS_MONTHLY_PRIVATE_TESTS', { - usedTestsMessage: usedTestsMessage(warning.limit, 'private test'), + limit: warning.limit, + usedTestsMessage: 'private test', gracePeriodMessage: gracePeriodMessage(warning.gracePeriodEnds), link: billingLink(warning.orgId), }) case 'FREE_PLAN_IN_GRACE_PERIOD_EXCEEDS_MONTHLY_TESTS': return errors.warning('FREE_PLAN_IN_GRACE_PERIOD_EXCEEDS_MONTHLY_TESTS', { - usedTestsMessage: usedTestsMessage(warning.limit, 'test'), + limit: warning.limit, + usedTestsMessage: 'test', gracePeriodMessage: gracePeriodMessage(warning.gracePeriodEnds), link: billingLink(warning.orgId), }) @@ -356,19 +350,22 @@ const createRun = Promise.method((options = {}) => { case 'FREE_PLAN_EXCEEDS_MONTHLY_TESTS_V2': return errors.warning('PLAN_EXCEEDS_MONTHLY_TESTS', { planType: 'free', - usedTestsMessage: usedTestsMessage(warning.limit, 'test'), + limit: warning.limit, + usedTestsMessage: 'test', link: billingLink(warning.orgId), }) case 'PAID_PLAN_EXCEEDS_MONTHLY_PRIVATE_TESTS': return errors.warning('PLAN_EXCEEDS_MONTHLY_TESTS', { planType: 'current', - usedTestsMessage: usedTestsMessage(warning.limit, 'private test'), + limit: warning.limit, + usedTestsMessage: 'private test', link: billingLink(warning.orgId), }) case 'PAID_PLAN_EXCEEDS_MONTHLY_TESTS': return errors.warning('PLAN_EXCEEDS_MONTHLY_TESTS', { planType: 'current', - usedTestsMessage: usedTestsMessage(warning.limit, 'test'), + limit: warning.limit, + usedTestsMessage: 'test', link: billingLink(warning.orgId), }) case 'PLAN_IN_GRACE_PERIOD_RUN_GROUPING_FEATURE_USED': @@ -398,7 +395,7 @@ const createRun = Promise.method((options = {}) => { recordKey = 'undefined' } - return errors.throw('DASHBOARD_RECORD_KEY_NOT_VALID', recordKey, projectId) + return errors.throwErr('DASHBOARD_RECORD_KEY_NOT_VALID', recordKey, projectId) case 402: { const { code, payload } = err.error @@ -407,25 +404,27 @@ const createRun = Promise.method((options = {}) => { switch (code) { case 'FREE_PLAN_EXCEEDS_MONTHLY_PRIVATE_TESTS': - return errors.throw('FREE_PLAN_EXCEEDS_MONTHLY_PRIVATE_TESTS', { - usedTestsMessage: usedTestsMessage(limit, 'private test'), + return errors.throwErr('FREE_PLAN_EXCEEDS_MONTHLY_PRIVATE_TESTS', { + limit, + usedTestsMessage: 'private test', link: billingLink(orgId), }) case 'FREE_PLAN_EXCEEDS_MONTHLY_TESTS': - return errors.throw('FREE_PLAN_EXCEEDS_MONTHLY_TESTS', { - usedTestsMessage: usedTestsMessage(limit, 'test'), + return errors.throwErr('FREE_PLAN_EXCEEDS_MONTHLY_TESTS', { + limit, + usedTestsMessage: 'test', link: billingLink(orgId), }) case 'PARALLEL_FEATURE_NOT_AVAILABLE_IN_PLAN': - return errors.throw('PARALLEL_FEATURE_NOT_AVAILABLE_IN_PLAN', { + return errors.throwErr('PARALLEL_FEATURE_NOT_AVAILABLE_IN_PLAN', { link: billingLink(orgId), }) case 'RUN_GROUPING_FEATURE_NOT_AVAILABLE_IN_PLAN': - return errors.throw('RUN_GROUPING_FEATURE_NOT_AVAILABLE_IN_PLAN', { + return errors.throwErr('RUN_GROUPING_FEATURE_NOT_AVAILABLE_IN_PLAN', { link: billingLink(orgId), }) default: - return errors.throw('DASHBOARD_UNKNOWN_INVALID_REQUEST', { + return errors.throwErr('DASHBOARD_UNKNOWN_INVALID_REQUEST', { response: err, flags: { group, @@ -437,9 +436,9 @@ const createRun = Promise.method((options = {}) => { } } case 404: - return errors.throw('DASHBOARD_PROJECT_NOT_FOUND', projectId, path.basename(options.configFile)) + return errors.throwErr('DASHBOARD_PROJECT_NOT_FOUND', projectId, path.basename(options.configFile)) case 412: - return errors.throw('DASHBOARD_INVALID_RUN_REQUEST', err.error) + return errors.throwErr('DASHBOARD_INVALID_RUN_REQUEST', err.error) case 422: { const { code, payload } = err.error @@ -447,7 +446,7 @@ const createRun = Promise.method((options = {}) => { switch (code) { case 'RUN_GROUP_NAME_NOT_UNIQUE': - return errors.throw('DASHBOARD_RUN_GROUP_NAME_NOT_UNIQUE', { + return errors.throwErr('DASHBOARD_RUN_GROUP_NAME_NOT_UNIQUE', { group, runUrl, ciBuildId, @@ -455,7 +454,7 @@ const createRun = Promise.method((options = {}) => { case 'PARALLEL_GROUP_PARAMS_MISMATCH': { const { browserName, browserVersion, osName, osVersion } = platform - return errors.throw('DASHBOARD_PARALLEL_GROUP_PARAMS_MISMATCH', { + return errors.throwErr('DASHBOARD_PARALLEL_GROUP_PARAMS_MISMATCH', { group, runUrl, ciBuildId, @@ -469,21 +468,21 @@ const createRun = Promise.method((options = {}) => { }) } case 'PARALLEL_DISALLOWED': - return errors.throw('DASHBOARD_PARALLEL_DISALLOWED', { + return errors.throwErr('DASHBOARD_PARALLEL_DISALLOWED', { tags, group, runUrl, ciBuildId, }) case 'PARALLEL_REQUIRED': - return errors.throw('DASHBOARD_PARALLEL_REQUIRED', { + return errors.throwErr('DASHBOARD_PARALLEL_REQUIRED', { tags, group, runUrl, ciBuildId, }) case 'ALREADY_COMPLETE': - return errors.throw('DASHBOARD_ALREADY_COMPLETE', { + return errors.throwErr('DASHBOARD_ALREADY_COMPLETE', { runUrl, tags, group, @@ -491,7 +490,7 @@ const createRun = Promise.method((options = {}) => { ciBuildId, }) case 'STALE_RUN': - return errors.throw('DASHBOARD_STALE_RUN', { + return errors.throwErr('DASHBOARD_STALE_RUN', { runUrl, tags, group, @@ -499,7 +498,7 @@ const createRun = Promise.method((options = {}) => { ciBuildId, }) default: - return errors.throw('DASHBOARD_UNKNOWN_INVALID_REQUEST', { + return errors.throwErr('DASHBOARD_UNKNOWN_INVALID_REQUEST', { response: err, flags: { tags, diff --git a/packages/server/lib/modes/run.js b/packages/server/lib/modes/run.js index 826eef16c3f3..ae37a74ead2f 100644 --- a/packages/server/lib/modes/run.js +++ b/packages/server/lib/modes/run.js @@ -168,7 +168,7 @@ const formatNodeVersion = ({ resolvedNodeVersion, resolvedNodePath }, width) => debug('formatting Node version. %o', { version: resolvedNodeVersion, path: resolvedNodePath }) if (resolvedNodePath) { - return formatPath(`v${resolvedNodeVersion} (${resolvedNodePath})`, width) + return formatPath(`v${resolvedNodeVersion} ${gray(`(${resolvedNodePath})`)}`, width) } } @@ -672,7 +672,7 @@ const removeOldProfiles = (browser) => { return browserUtils.removeOldProfiles(browser) .catch((err) => { // dont make removing old browsers profiles break the build - return errors.warning('CANNOT_REMOVE_OLD_BROWSER_PROFILES', err.stack) + return errors.warning('CANNOT_REMOVE_OLD_BROWSER_PROFILES', err) }) } @@ -688,7 +688,7 @@ const trashAssets = Promise.method((config = {}) => { ]) .catch((err) => { // dont make trashing assets fail the build - return errors.warning('CANNOT_TRASH_ASSETS', err.stack) + return errors.warning('CANNOT_TRASH_ASSETS', err) }) }) @@ -698,7 +698,7 @@ const createVideoRecording = function (videoName, options = {}) { const onError = _.once((err) => { // catch video recording failures and log them out // but don't let this affect the run at all - return errors.warning('VIDEO_RECORDING_FAILED', err.stack) + return errors.warning('VIDEO_RECORDING_FAILED', err) }) return fs @@ -755,7 +755,7 @@ const maybeStartVideoRecording = Promise.method(function (options = {}) { const warnVideoRecordingFailed = (err) => { // log that post processing was attempted // but failed and dont let this change the run exit code - errors.warning('VIDEO_POST_PROCESSING_FAILED', err.stack) + errors.warning('VIDEO_POST_PROCESSING_FAILED', err) } module.exports = { @@ -1447,6 +1447,7 @@ module.exports = { }) if (browser.family !== 'chromium' && !options.config.chromeWebSecurity) { + console.log('') errors.warning('CHROME_WEB_SECURITY_NOT_SUPPORTED', browser.family) } @@ -1564,13 +1565,13 @@ module.exports = { ]) .spread(async (sys = {}, browser = {}) => { if (!project.ctx.project.specs.length) { - errors.throw('NO_SPECS_FOUND', projectRoot, specPattern) + errors.throwErr('NO_SPECS_FOUND', projectRoot, specPattern) } const specs = project.ctx.project.specs if (browser.unsupportedVersion && browser.warning) { - errors.throw('UNSUPPORTED_BROWSER_VERSION', browser.warning) + errors.throwErr('UNSUPPORTED_BROWSER_VERSION', browser.warning) } if (browser.family === 'chromium') { @@ -1582,7 +1583,6 @@ module.exports = { beforeSpecRun, afterSpecRun, projectRoot, - specPattern, socketId, parallel, onError, @@ -1594,6 +1594,7 @@ module.exports = { specs, sys, tag, + specPattern, videosFolder: config.videosFolder, video: config.video, videoCompression: config.videoCompression, diff --git a/packages/server/lib/open_project.ts b/packages/server/lib/open_project.ts index c4b681971e9c..1a2563bdc5d8 100644 --- a/packages/server/lib/open_project.ts +++ b/packages/server/lib/open_project.ts @@ -6,11 +6,11 @@ import assert from 'assert' import { ProjectBase } from './project-base' import browsers from './browsers' +import * as errors from './errors' import preprocessor from './plugins/preprocessor' import runEvents from './plugins/run_events' import * as session from './session' import { getSpecUrl } from './project_utils' -import errors from './errors' import type { LaunchOpts, OpenProjectLaunchOptions, InitializeProjectOptions } from '@packages/types' import { DataContext, getCtx } from '@packages/data-context' import { autoBindDebug } from '@packages/data-context/src/util' @@ -281,7 +281,7 @@ export class OpenProject { await this.projectBase.open() } catch (err: any) { if (err.isCypressErr && err.portInUse) { - errors.throw(err.type, err.port) + errors.throwErr(err.type, err.port) } else { // rethrow and handle elsewhere throw (err) diff --git a/packages/server/lib/plugins/child/browser_launch.js b/packages/server/lib/plugins/child/browser_launch.js index 91d402999859..c5680961e3d8 100644 --- a/packages/server/lib/plugins/child/browser_launch.js +++ b/packages/server/lib/plugins/child/browser_launch.js @@ -1,5 +1,4 @@ const util = require('../util') -const errors = require('../../errors') const ARRAY_METHODS = ['concat', 'push', 'unshift', 'slice', 'pop', 'shift', 'slice', 'splice', 'filter', 'map', 'forEach', 'reduce', 'reverse', 'splice', 'includes'] @@ -21,7 +20,9 @@ module.exports = { hasEmittedWarning = true - const warning = errors.get('DEPRECATED_BEFORE_BROWSER_LAUNCH_ARGS') + const warning = require('@packages/errors').getError( + 'DEPRECATED_BEFORE_BROWSER_LAUNCH_ARGS', + ) ipc.send('warning', util.serializeError(warning)) diff --git a/packages/server/lib/plugins/child/run_plugins.js b/packages/server/lib/plugins/child/run_plugins.js index 9be0556dab3f..320a1a24f789 100644 --- a/packages/server/lib/plugins/child/run_plugins.js +++ b/packages/server/lib/plugins/child/run_plugins.js @@ -14,14 +14,19 @@ const resolve = require('../../util/resolve') const browserLaunch = require('./browser_launch') const util = require('../util') const validateEvent = require('./validate_event') -const errors = require('../../errors') const UNDEFINED_SERIALIZED = '__cypress_undefined__' class RunPlugins { constructor (ipc, projectRoot, requiredFile) { this.ipc = ipc + /** + * @type {string} + */ this.projectRoot = projectRoot + /** + * @type {string} + */ this.requiredFile = requiredFile this.eventIdCount = 0 this.registrations = [] @@ -57,16 +62,22 @@ class RunPlugins { // we track the register calls and then send them all at once // to the parent process const registerChildEvent = (event, handler) => { - const { isValid, error } = validateEvent(event, handler, initialConfig) + const { isValid, userEvents, error } = validateEvent(event, handler, initialConfig) if (!isValid) { - this.ipc.send('setupTestingType:error', 'PLUGINS_VALIDATION_ERROR', this.requiredFile, error.stack) + const err = userEvents + ? require('@packages/errors').getError('PLUGINS_INVALID_EVENT_NAME_ERROR', this.requiredFile, event, userEvents, error) + : require('@packages/errors').getError('CONFIG_FILE_SETUP_NODE_EVENTS_ERROR', this.requiredFile, initialConfig.testingType, error) + + this.ipc.send('setupTestingType:error', util.serializeError(err)) return } if (event === 'dev-server:start' && this.registeredEventsByName[event]) { - this.ipc.send('setupTestingType:error', 'SETUP_NODE_EVENTS_DO_NOT_SUPPORT_DEV_SERVER', this.requiredFile) + const err = require('@packages/errors').getError('SETUP_NODE_EVENTS_DO_NOT_SUPPORT_DEV_SERVER', this.requiredFile) + + this.ipc.send('setupTestingType:error', util.serializeError(err)) return } @@ -122,7 +133,12 @@ class RunPlugins { }) .catch((err) => { debug('plugins file errored:', err && err.stack) - this.ipc.send('setupTestingType:error', 'PLUGINS_FUNCTION_ERROR', err.stack) + this.ipc.send('setupTestingType:error', util.serializeError(require('@packages/errors').getError( + 'CONFIG_FILE_SETUP_NODE_EVENTS_ERROR', + this.requiredFile, + initialConfig.testingType, + err, + ))) }) } @@ -168,7 +184,7 @@ class RunPlugins { return this.ipc.send(`promise:fulfilled:${ids.invocationId}`, null, value) }).catch((err) => { - return this.ipc.send(`promise:fulfilled:${ids.invocationId}`, serializeError(err)) + return this.ipc.send(`promise:fulfilled:${ids.invocationId}`, util.serializeError(err)) }) } @@ -195,7 +211,7 @@ class RunPlugins { const duplicates = _.intersection(_.keys(target), _.keys(events)) if (duplicates.length) { - errors.warning('DUPLICATE_TASK_KEY', duplicates.join(', ')) + require('@packages/errors').warning('DUPLICATE_TASK_KEY', duplicates) } return _.extend(target, events) @@ -243,8 +259,4 @@ class RunPlugins { } } -const serializeError = (err) => { - return _.pick(err, 'name', 'message', 'stack', 'code', 'annotated', 'type') -} - exports.RunPlugins = RunPlugins diff --git a/packages/server/lib/plugins/child/run_require_async_child.js b/packages/server/lib/plugins/child/run_require_async_child.js index 0327533fcbc0..1d5b5ba84b27 100644 --- a/packages/server/lib/plugins/child/run_require_async_child.js +++ b/packages/server/lib/plugins/child/run_require_async_child.js @@ -15,8 +15,6 @@ let tsRegistered = false * @returns */ function run (ipc, configFile, projectRoot) { - let areSetupNodeEventsLoaded = false - debug('configFile:', configFile) debug('projectRoot:', projectRoot) if (!projectRoot) { @@ -33,7 +31,7 @@ function run (ipc, configFile, projectRoot) { process.on('uncaughtException', (err) => { debug('uncaught exception:', util.serializeError(err)) - ipc.send(areSetupNodeEventsLoaded ? 'childProcess:unhandledError' : 'setupTestingType:uncaughtError', util.serializeError(err)) + ipc.send('childProcess:unhandledError', util.serializeError(err)) return false }) @@ -54,9 +52,11 @@ function run (ipc, configFile, projectRoot) { return false }) - const isValidSetupNodeEvents = (setupNodeEvents) => { - if (setupNodeEvents && typeof setupNodeEvents !== 'function') { - ipc.send('setupTestingType:error', 'SETUP_NODE_EVENTS_IS_NOT_FUNCTION', configFile, setupNodeEvents) + const isValidSetupNodeEvents = (config, testingType) => { + if (config[testingType] && config[testingType].setupNodeEvents && typeof config[testingType].setupNodeEvents !== 'function') { + ipc.send('setupTestingType:error', util.serializeError( + require('@packages/errors').getError('SETUP_NODE_EVENTS_IS_NOT_FUNCTION', configFile, testingType, config[testingType].setupNodeEvents), + )) return false } @@ -71,7 +71,9 @@ function run (ipc, configFile, projectRoot) { return true } - ipc.send('setupTestingType:error', 'COMPONENT_DEV_SERVER_IS_NOT_A_FUNCTION', configFile, config) + ipc.send('setupTestingType:error', util.serializeError( + require('@packages/errors').getError('CONFIG_FILE_DEV_SERVER_IS_NOT_A_FUNCTION', configFile, config), + )) return false } @@ -102,9 +104,12 @@ function run (ipc, configFile, projectRoot) { const runPlugins = new RunPlugins(ipc, projectRoot, configFile) - areSetupNodeEventsLoaded = true + if (!isValidSetupNodeEvents(result, testingType)) { + return + } + if (testingType === 'component') { - if (!isValidSetupNodeEvents(result.setupNodeEvents) || !isValidDevServer((result.component || {}))) { + if (!isValidDevServer((result.component || {}))) { return } @@ -118,10 +123,6 @@ function run (ipc, configFile, projectRoot) { return setupNodeEvents(on, config) }) } else if (testingType === 'e2e') { - if (!isValidSetupNodeEvents(result.e2e && result.e2e.setupNodeEvents)) { - return - } - const setupNodeEvents = result.e2e && result.e2e.setupNodeEvents || ((on, config) => {}) runPlugins.runSetupNodeEvents(options, setupNodeEvents) @@ -142,14 +143,13 @@ function run (ipc, configFile, projectRoot) { // replace the first line with better text (remove potentially misleading word TypeScript for example) .replace(/^.*\n/g, 'Error compiling file\n') - ipc.send('loadConfig:error', err.name, configFile, cleanMessage) - } else { - const realErrorCode = err.code || err.name - - debug('failed to load file:%s\n%s: %s', configFile, realErrorCode, err.message) - - ipc.send('loadConfig:error', realErrorCode, configFile, err.message) + err.originalMessage = err.message + err.message = cleanMessage } + + ipc.send('loadConfig:error', util.serializeError( + require('@packages/errors').getError('CONFIG_FILE_REQUIRE_ERROR', configFile, err), + )) } }) } diff --git a/packages/server/lib/plugins/child/validate_event.js b/packages/server/lib/plugins/child/validate_event.js index 40f984b3f712..561377e95895 100644 --- a/packages/server/lib/plugins/child/validate_event.js +++ b/packages/server/lib/plugins/child/validate_event.js @@ -1,7 +1,15 @@ const _ = require('lodash') -const createErrorResult = (errorMessage) => ({ isValid: false, error: new Error(errorMessage) }) -const createSuccessResult = () => ({ isValid: true }) +const createErrorResult = (errorMessage) => { + return { + isValid: false, + error: new Error(errorMessage), + } +} + +const createSuccessResult = () => { + return { isValid: true } +} const validate = (func, arg, errorMessage) => { return func(arg) ? createSuccessResult() : createErrorResult(errorMessage) @@ -29,22 +37,34 @@ const eventValidators = { 'task': isObject, } -const validateEvent = (event, handler, config) => { +const validateEvent = (event, handler, config, errConstructorFn) => { const validator = eventValidators[event] if (!validator) { const userEvents = _.reject(_.keys(eventValidators), (event) => event.startsWith('_')) - return createErrorResult(`You must pass a valid event name when registering a plugin. + const error = new Error(`invalid event name registered: ${event}`) + + error.name = 'InvalidEventNameError' + + Error.captureStackTrace(error, errConstructorFn) + + return { + error, + userEvents, + isValid: false, + } + } + + const result = validator(event, handler, config) -You passed: \`${event}\` + if (!result.isValid) { + result.error.name = 'InvalidEventHandlerError' -The following are valid events: -- ${userEvents.join('\n- ')} -`) + Error.captureStackTrace(result.error, errConstructorFn) } - return validator(event, handler, config) + return result } module.exports = validateEvent diff --git a/packages/server/lib/plugins/dev-server.js b/packages/server/lib/plugins/dev-server.js index d54ba444367c..451636e8960d 100644 --- a/packages/server/lib/plugins/dev-server.js +++ b/packages/server/lib/plugins/dev-server.js @@ -33,7 +33,7 @@ const API = { start ({ specs, config }) { if (!plugins.has('dev-server:start')) { - throw errors.get('CT_NO_DEV_START_EVENT', config.pluginsFile) + throw errors.get('CONFIG_FILE_INVALID_DEV_START_EVENT', config.pluginsFile) } return plugins.execute('dev-server:start', { specs, config }) diff --git a/packages/server/lib/plugins/run_events.js b/packages/server/lib/plugins/run_events.js index 6f73c8bfab7c..d197b35773ba 100644 --- a/packages/server/lib/plugins/run_events.js +++ b/packages/server/lib/plugins/run_events.js @@ -11,7 +11,7 @@ module.exports = { .catch((err) => { err = err || {} - errors.throw('PLUGINS_RUN_EVENT_ERROR', eventName, err.stack || err.message || err) + errors.throwErr('PLUGINS_RUN_EVENT_ERROR', eventName, err) }) }), } diff --git a/packages/server/lib/plugins/util.js b/packages/server/lib/plugins/util.js index f849ad2de914..d332d9803309 100644 --- a/packages/server/lib/plugins/util.js +++ b/packages/server/lib/plugins/util.js @@ -5,7 +5,13 @@ const Promise = require('bluebird') const UNDEFINED_SERIALIZED = '__cypress_undefined__' const serializeError = (err) => { - return _.pick(err, 'name', 'message', 'stack', 'code', 'annotated', 'type') + const obj = _.pick(err, 'name', 'message', 'stack', 'code', 'annotated', 'type', 'details', 'isCypressErr', 'messageMarkdown', 'originalError') + + if (obj.originalError) { + obj.originalError = serializeError(obj.originalError) + } + + return obj } module.exports = { diff --git a/packages/server/lib/project-base.ts b/packages/server/lib/project-base.ts index 66e9ae8a7fca..07dbf95c929f 100644 --- a/packages/server/lib/project-base.ts +++ b/packages/server/lib/project-base.ts @@ -3,31 +3,28 @@ import Debug from 'debug' import EE from 'events' import _ from 'lodash' import path from 'path' -import { createHmac } from 'crypto' - -import browsers from './browsers' import pkg from '@packages/root' -// import { allowed } from '@packages/config' -import { ServerCt } from './server-ct' -import { SocketCt } from './socket-ct' -import { SocketE2E } from './socket-e2e' import { Automation } from './automation' +import browsers from './browsers' import * as config from './config' -import cwd from './cwd' -import errors from './errors' -import Reporter from './reporter' +import * as errors from './errors' +import devServer from './plugins/dev-server' +import preprocessor from './plugins/preprocessor' import runEvents from './plugins/run_events' +import { checkSupportFile } from './project_utils' +import Reporter from './reporter' import * as savedState from './saved_state' +import { ServerCt } from './server-ct' import { ServerE2E } from './server-e2e' -import system from './util/system' +import { SocketCt } from './socket-ct' +import { SocketE2E } from './socket-e2e' import { ensureProp } from './util/class-helpers' import { fs } from './util/fs' -import preprocessor from './plugins/preprocessor' -import { checkSupportFile } from './project_utils' -import type { FoundBrowser, OpenProjectLaunchOptions, FoundSpec, TestingType, ReceivedCypressOptions } from '@packages/types' -import devServer from './plugins/dev-server' +import system from './util/system' +import type { FoundBrowser, FoundSpec, OpenProjectLaunchOptions, ReceivedCypressOptions, TestingType } from '@packages/types' import { DataContext, getCtx } from '@packages/data-context' +import { createHmac } from 'crypto' export interface Cfg extends ReceivedCypressOptions { projectRoot: string @@ -43,7 +40,7 @@ export interface Cfg extends ReceivedCypressOptions { component: Partial } -const localCwd = cwd() +const localCwd = process.cwd() const debug = Debug('cypress:server:project') @@ -373,16 +370,12 @@ export class ProjectBase extends EE { try { Reporter.loadReporter(reporter, projectRoot) - } catch (err: any) { + } catch (error: any) { const paths = Reporter.getSearchPathsForReporter(reporter, projectRoot) - // only include the message if this is the standard MODULE_NOT_FOUND - // else include the whole stack - const errorMsg = err.code === 'MODULE_NOT_FOUND' ? err.message : err.stack - - errors.throw('INVALID_REPORTER_NAME', { + errors.throwErr('INVALID_REPORTER_NAME', { paths, - error: errorMsg, + error, name: reporter, }) } diff --git a/packages/server/lib/project_utils.ts b/packages/server/lib/project_utils.ts index 0656165b26f9..3e7b9d245945 100644 --- a/packages/server/lib/project_utils.ts +++ b/packages/server/lib/project_utils.ts @@ -1,9 +1,8 @@ import Debug from 'debug' import path from 'path' - -import errors from './errors' -import { fs } from './util/fs' +import * as errors from './errors' import { escapeFilenameInUrl } from './util/escape_filename' +import { fs } from './util/fs' const debug = Debug('cypress:server:project_utils') @@ -48,7 +47,7 @@ export const checkSupportFile = async ({ const found = await fs.pathExists(supportFile) if (!found) { - errors.throw('SUPPORT_FILE_NOT_FOUND', supportFile, configFile) + errors.throwErr('SUPPORT_FILE_NOT_FOUND', supportFile) } } diff --git a/packages/server/lib/reporter.js b/packages/server/lib/reporter.js index 5c5b6135c87e..ceac97f2c4ff 100644 --- a/packages/server/lib/reporter.js +++ b/packages/server/lib/reporter.js @@ -1,6 +1,6 @@ const _ = require('lodash') const path = require('path') -const stackUtils = require('./util/stack_utils') +const { stackUtils } = require('@packages/errors') // mocha-* is used to allow us to have later versions of mocha specified in devDependencies // and prevents accidently upgrading this one // TODO: look into upgrading this to version in driver diff --git a/packages/server/lib/server-base.ts b/packages/server/lib/server-base.ts index bd9c68438b3c..ee3a30afd2e3 100644 --- a/packages/server/lib/server-base.ts +++ b/packages/server/lib/server-base.ts @@ -15,7 +15,7 @@ import { netStubbingState, NetStubbingState } from '@packages/net-stubbing' import { agent, clientCertificates, cors, httpUtils, uri } from '@packages/network' import { NetworkProxy, BrowserPreRequest } from '@packages/proxy' import type { SocketCt } from './socket-ct' -import errors from './errors' +import * as errors from './errors' import Request from './request' import type { SocketE2E } from './socket-e2e' import templateEngine from './template_engine' diff --git a/packages/server/lib/server-e2e.ts b/packages/server/lib/server-e2e.ts index 531962cedc91..096f46faac02 100644 --- a/packages/server/lib/server-e2e.ts +++ b/packages/server/lib/server-e2e.ts @@ -7,7 +7,7 @@ import url from 'url' import httpsProxy from '@packages/https-proxy' import { getRouteForRequest } from '@packages/net-stubbing' import { concatStream, cors } from '@packages/network' -import errors from './errors' +import * as errors from './errors' import fileServer from './file_server' import { OpenServerOptions, ServerBase } from './server-base' import type { SocketE2E } from './socket-e2e' @@ -107,7 +107,7 @@ export class ServerE2E extends ServerBase { .catch((e) => { debug(e) - return reject(errors.get('CANNOT_CONNECT_BASE_URL', baseUrl)) + return reject(errors.get('CANNOT_CONNECT_BASE_URL')) }) } diff --git a/packages/server/lib/socket-base.ts b/packages/server/lib/socket-base.ts index 92945d32cd8e..6e6b43d67982 100644 --- a/packages/server/lib/socket-base.ts +++ b/packages/server/lib/socket-base.ts @@ -4,7 +4,7 @@ import _ from 'lodash' import { onNetStubbingEvent } from '@packages/net-stubbing' import * as socketIo from '@packages/socket' import firefoxUtil from './browsers/firefox-util' -import errors from './errors' +import * as errors from './errors' import exec from './exec' import files from './files' import fixture from './fixture' @@ -274,7 +274,7 @@ export class SocketBase { .then((resp) => { return cb({ response: resp }) }).catch((err) => { - return cb({ error: errors.clone(err) }) + return cb({ error: errors.cloneErr(err) }) }) }) @@ -459,7 +459,7 @@ export class SocketBase { .then((resp) => { return cb({ response: resp }) }).catch((err) => { - return cb({ error: errors.clone(err) }) + return cb({ error: errors.cloneErr(err) }) }) }) diff --git a/packages/server/lib/util/args.js b/packages/server/lib/util/args.js index c04747c1461f..af475e0b06f7 100644 --- a/packages/server/lib/util/args.js +++ b/packages/server/lib/util/args.js @@ -163,8 +163,8 @@ const JSONOrCoerce = (str) => { return coerceUtil.coerce(str) } -const sanitizeAndConvertNestedArgs = (str, argname) => { - la(is.unemptyString(argname), 'missing config argname to be parsed') +const sanitizeAndConvertNestedArgs = (str, argName) => { + la(is.unemptyString(argName), 'missing config argName to be parsed') try { if (typeof str === 'object') { @@ -197,10 +197,10 @@ const sanitizeAndConvertNestedArgs = (str, argname) => { .mapValues(JSONOrCoerce) .value() } catch (err) { - debug('could not pass config %s value %s', argname, str) + debug('could not pass config %s value %s', argName, str) debug('error %o', err) - return errors.throw('COULD_NOT_PARSE_ARGUMENTS', argname, str, 'Cannot parse as valid JSON') + return errors.throwErr('COULD_NOT_PARSE_ARGUMENTS', argName, str, 'Cannot parse as valid JSON') } } @@ -421,7 +421,7 @@ module.exports = { debug('could not parse config spec value %s', spec) debug('error %o', err) - return errors.throw('COULD_NOT_PARSE_ARGUMENTS', 'spec', spec, 'spec must be a string or comma-separated list') + return errors.throwErr('COULD_NOT_PARSE_ARGUMENTS', 'spec', spec, 'spec must be a string or comma-separated list') } } diff --git a/packages/server/lib/util/ensure-url.ts b/packages/server/lib/util/ensure-url.ts index 776d1e6ac54b..5b644218b67f 100644 --- a/packages/server/lib/util/ensure-url.ts +++ b/packages/server/lib/util/ensure-url.ts @@ -9,7 +9,7 @@ const debug = debugModule('cypress:server:ensure-url') type RetryOptions = { retryIntervals: number[] - onRetry: Function + onRetry(o: {delay: number, attempt: number, remaining: number}): void } export const retryIsListening = (urlStr: string, options: RetryOptions) => { diff --git a/packages/server/lib/util/settings.ts b/packages/server/lib/util/settings.ts index 1b2ce8d115ff..1e3c1bd02e96 100644 --- a/packages/server/lib/util/settings.ts +++ b/packages/server/lib/util/settings.ts @@ -1,10 +1,10 @@ +import Debug from 'debug' import _ from 'lodash' import path from 'path' -import errors from '../errors' import { fs } from '../util/fs' -import Debug from 'debug' import type { SettingsOptions } from '@packages/types' import { getCtx } from '@packages/data-context' +import * as errors from '../errors' const debug = Debug('cypress:server:settings') diff --git a/packages/server/test/integration/cli_spec.js b/packages/server/test/integration/cli_spec.js index 11f5609bd532..44a2fb739075 100644 --- a/packages/server/test/integration/cli_spec.js +++ b/packages/server/test/integration/cli_spec.js @@ -44,7 +44,8 @@ describe('CLI Interface', () => { }) }) - xit('writes out package.json and exits', (done) => { + // TODO:(tgriesser) originally skipped this, not sure why + it.skip('writes out package.json and exits', (done) => { return cp.exec('npm run dev -- --return-pkg', { env }, (err, stdout, stderr) => { if (err) { done(err) diff --git a/packages/server/test/integration/cypress_spec.js b/packages/server/test/integration/cypress_spec.js index 5ebb379310cc..4bcc2bc48178 100644 --- a/packages/server/test/integration/cypress_spec.js +++ b/packages/server/test/integration/cypress_spec.js @@ -160,11 +160,11 @@ describe('lib/cypress', () => { const err = errors.log.getCall(0).args[0] if (msg1) { - expect(err.message, 'error text').to.include(msg1) + expect(stripAnsi(err.message), 'error text').to.include(msg1) } if (msg2) { - expect(err.message, 'second error text').to.include(msg2) + expect(stripAnsi(err.message), 'second error text').to.include(msg2) } return err @@ -260,7 +260,8 @@ describe('lib/cypress', () => { return cypress.start(['--config=test=false', '--cwd=/foo/bar']) .then(() => { expect(errors.warning).to.be.calledWith('INVALID_CONFIG_OPTION') - expect(console.log).to.be.calledWithMatch('`test` is not a valid configuration option') + expect(console.log).to.be.calledWithMatch('The following configuration option is invalid:') + expect(console.log).to.be.calledWithMatch(`test`) expect(console.log).to.be.calledWithMatch('https://on.cypress.io/configuration') }) }) @@ -269,8 +270,9 @@ describe('lib/cypress', () => { return cypress.start(['--config=test=false,foo=bar', '--cwd=/foo/bar']) .then(() => { expect(errors.warning).to.be.calledWith('INVALID_CONFIG_OPTION') - expect(console.log).to.be.calledWithMatch('`test` is not a valid configuration option') - expect(console.log).to.be.calledWithMatch('`foo` is not a valid configuration option') + expect(console.log).to.be.calledWithMatch('The following configuration options are invalid:') + expect(console.log).to.be.calledWithMatch('test') + expect(console.log).to.be.calledWithMatch('foo') expect(console.log).to.be.calledWithMatch('https://on.cypress.io/configuration') snapshotConsoleLogs('INVALID_CONFIG_OPTION') @@ -592,7 +594,7 @@ describe('lib/cypress', () => { return cypress.start([`--run-project=${this.todosPath}`, '--key=asdf']) .then(() => { expect(errors.warning).to.be.calledWith('PROJECT_ID_AND_KEY_BUT_MISSING_RECORD_OPTION', 'abc123') - expect(console.log).to.be.calledWithMatch('You also provided your Record Key, but you did not pass the --record flag.') + expect(console.log).to.be.calledWithMatch('You also provided your Record Key, but you did not pass the') expect(console.log).to.be.calledWithMatch('cypress run --record') expect(console.log).to.be.calledWithMatch('https://on.cypress.io/recording-project-runs') }) @@ -605,7 +607,7 @@ describe('lib/cypress', () => { return cypress.start([`--run-project=${this.todosPath}`]) .then(() => { - expect(errors.warning).to.be.calledWith('CANNOT_REMOVE_OLD_BROWSER_PROFILES', err.stack) + expect(errors.warning).to.be.calledWith('CANNOT_REMOVE_OLD_BROWSER_PROFILES', err) expect(console.log).to.be.calledWithMatch('Warning: We failed to remove old browser profiles from previous runs.') expect(console.log).to.be.calledWithMatch(err.message) }) @@ -631,8 +633,9 @@ describe('lib/cypress', () => { return settings.writeForTesting(this.idsPath, { e2e: { supportFile: '/does/not/exist' } }) .then(() => { return cypress.start([`--run-project=${this.idsPath}`]) - }).then(() => { - this.expectExitWithErr('SUPPORT_FILE_NOT_FOUND', 'Your `supportFile` is set to `/does/not/exist`,') + }) + .then(() => { + this.expectExitWithErr('SUPPORT_FILE_NOT_FOUND', `Your supportFile is missing or invalid: /does/not/exist`) }) }) @@ -648,17 +651,17 @@ describe('lib/cypress', () => { const found1 = _.find(argsSet, (args) => { return _.find(args, (arg) => { - return arg.message && arg.message.includes( - 'The specified browser was not found on your system or is not supported by Cypress: `foo`', + return arg.message && stripAnsi(arg.message).includes( + `Browser: foo was not found on your system or is not supported by Cypress.`, ) }) }) - expect(found1, 'foo should not be found').to.be.ok + expect(found1, `foo should not be found`).to.be.ok const found2 = _.find(argsSet, (args) => { return _.find(args, (arg) => { - return arg.message && arg.message.includes( + return arg.message && stripAnsi(arg.message).includes( 'Cypress supports the following browsers:', ) }) @@ -668,8 +671,8 @@ describe('lib/cypress', () => { const found3 = _.find(argsSet, (args) => { return _.find(args, (arg) => { - return arg.message && arg.message.includes( - 'Available browsers found on your system are:\n- chrome\n- chromium\n- chrome:canary\n- electron', + return arg.message && stripAnsi(arg.message).includes( + 'Available browsers found on your system are:\n - chrome\n - chromium\n - chrome:canary\n - electron', ) }) }) @@ -680,26 +683,62 @@ describe('lib/cypress', () => { describe('no specs found', function () { it('logs error and exits when spec file was specified and does not exist', function () { - return cypress.start([`--run-project=${this.todosPath}`, '--spec=path/to/spec']) + const cwd = process.cwd() + + return cypress.start([ + `--cwd=${cwd}`, + `--run-project=${this.todosPath}`, + '--spec=path/to/spec', + ]) .then(() => { // includes the search spec - this.expectExitWithErr('NO_SPECS_FOUND', 'path/to/spec') - this.expectExitWithErr('NO_SPECS_FOUND', 'We searched for any files matching this glob pattern:') + this.expectExitWithErr('NO_SPECS_FOUND', 'We searched for specs matching this glob pattern:') // includes the project path - this.expectExitWithErr('NO_SPECS_FOUND', this.todosPath) + this.expectExitWithErr('NO_SPECS_FOUND', path.join(cwd, 'path/to/spec')) + }) + }) + + it('logs error and exits when spec file was specified and does not exist using ../ pattern', function () { + const cwd = process.cwd() + + return cypress.start([ + `--cwd=${cwd}`, + `--run-project=${this.todosPath}`, + '--spec=../path/to/spec', + ]) + .then(() => { + // includes the search spec + this.expectExitWithErr('NO_SPECS_FOUND', 'We searched for specs matching this glob pattern:') + // includes the project path + this.expectExitWithErr('NO_SPECS_FOUND', path.join(cwd, '../path/to/spec')) + }) + }) + + it('logs error and exits when spec file was specified with glob and does not exist using ../ pattern', function () { + const cwd = process.cwd() + + return cypress.start([ + `--cwd=${cwd}`, + `--run-project=${this.todosPath}`, + '--spec=../path/to/**/*', + ]) + .then(() => { + // includes the search spec + this.expectExitWithErr('NO_SPECS_FOUND', 'We searched for specs matching this glob pattern:') + // includes the project path + this.expectExitWithErr('NO_SPECS_FOUND', path.join(cwd, '../path/to/**/*')) }) }) it('logs error and exits when spec absolute file was specified and does not exist', function () { return cypress.start([ `--run-project=${this.todosPath}`, - `--spec=${this.todosPath}/tests/path/to/spec`, + `--spec=/path/to/spec`, ]) .then(() => { - // includes path to the spec - this.expectExitWithErr('NO_SPECS_FOUND', 'tests/path/to/spec') - // includes folder name - this.expectExitWithErr('NO_SPECS_FOUND', this.todosPath) + // includes folder name + path to the spec + this.expectExitWithErr('NO_SPECS_FOUND', `/path/to/spec`) + expect(errors.log).not.to.be.calledWithMatch(this.todospath) }) }) @@ -709,7 +748,7 @@ describe('lib/cypress', () => { '--spec=/this/does/not/exist/**/*', ]) .then(() => { - this.expectExitWithErr('NO_SPECS_FOUND', 'We searched for any files matching this glob pattern') + this.expectExitWithErr('NO_SPECS_FOUND', 'We searched for specs matching this glob pattern') this.expectExitWithErr('NO_SPECS_FOUND', 'this/does/not/exist/**/*') }) }) @@ -739,7 +778,7 @@ describe('lib/cypress', () => { .then(() => { return cypress.start([`--run-project=${this.todosPath}`]) }).then(() => { - this.expectExitWithErr('SETTINGS_VALIDATION_ERROR', 'cypress.config.js') + this.expectExitWithErr('CONFIG_VALIDATION_ERROR', 'cypress.config.js') }) }) @@ -750,7 +789,7 @@ describe('lib/cypress', () => { ]) .then(() => { this.expectExitWithErr('CONFIG_VALIDATION_ERROR', 'localhost:9999') - this.expectExitWithErr('CONFIG_VALIDATION_ERROR', 'We found an invalid configuration value') + this.expectExitWithErr('CONFIG_VALIDATION_ERROR', 'An invalid configuration value was set.') }) }) @@ -760,7 +799,7 @@ describe('lib/cypress', () => { return cypress.start([`--run-project=${this.todosPath}`]) .then(() => { this.expectExitWithErr('CONFIG_VALIDATION_ERROR', 'localhost:9999') - this.expectExitWithErr('CONFIG_VALIDATION_ERROR', 'We found an invalid configuration value') + this.expectExitWithErr('CONFIG_VALIDATION_ERROR', 'An invalid configuration value was set.') }) }) @@ -1145,7 +1184,7 @@ describe('lib/cypress', () => { ]).then(() => { // uses default specPattern which is cypress/integration/**/* // exits with 1 since there are not specs for this pristine project. - this.expectExitWithErr('NO_SPECS_FOUND', 'We searched for any files matching this glob pattern:') + this.expectExitWithErr('NO_SPECS_FOUND', 'We searched for specs matching this glob pattern:') this.expectExitWithErr('NO_SPECS_FOUND', 'Can\'t run because no spec files were found') this.expectExitWith(1) }) @@ -1764,19 +1803,23 @@ describe('lib/cypress', () => { this.open = sinon.stub(ServerE2E.prototype, 'open').resolves([]) }) - it('reads config from a custom config file', function () { + // TODO: (tgriesser) needs a system test, the mocking here no longer is correct + it.skip('reads config from a custom config file', function () { + const bus = new EE() + return fs.writeJson(path.join(this.pristinePath, this.filename), { env: { foo: 'bar' }, port: 2020, }).then(() => { - cypress.start([ + return cypress.start([ `--config-file=${this.filename}`, ]) .then(() => { const options = Events.start.firstCall.args[0] - return Events.handleEvent(options, {}, {}, 123, 'open:project', this.pristinePath) - }).then(() => { + return Events.handleEvent(options, bus, {}, 123, 'open:project', this.pristinePath) + }) + .then(() => { expect(this.open).to.be.called const cfg = this.open.getCall(0).args[0] diff --git a/packages/server/test/integration/http_requests_spec.js b/packages/server/test/integration/http_requests_spec.js index 89212ba7bd3a..10f14c81fe79 100644 --- a/packages/server/test/integration/http_requests_spec.js +++ b/packages/server/test/integration/http_requests_spec.js @@ -210,7 +210,6 @@ describe('Routes', () => { afterEach(function () { evilDns.clear() nock.cleanAll() - Fixtures.remove() this.session.destroy() preprocessor.close() this.project = null @@ -220,6 +219,9 @@ describe('Routes', () => { httpsServer.stop(), ctx.actions.project.clearCurrentProject(), ) + .then(() => { + Fixtures.remove() + }) }) context('GET /', () => { @@ -456,7 +458,7 @@ describe('Routes', () => { if (i > 50) { throw Error(dedent` - setupNodeEvents and plugins did not complete after 10 seconds. + setupNodeEvents and plugins did not complete after 10 seconds. There might be an endless loop or an uncaught exception that isn't bubbling up.`) } }, 200) @@ -2006,7 +2008,7 @@ describe('Routes', () => { }) // https://github.com/cypress-io/cypress/issues/4267 - it('doesn\'t attach auth headers to a diff protection space on the same origin', function () { + it(`doesn't attach auth headers to a diff protection space on the same origin`, function () { return this.setup('http://beta.something.com') .then(() => { const username = 'u' diff --git a/packages/server/test/unit/api_spec.js b/packages/server/test/unit/api_spec.js index c220f9577454..11f00c88e7a4 100644 --- a/packages/server/test/unit/api_spec.js +++ b/packages/server/test/unit/api_spec.js @@ -919,7 +919,6 @@ describe('lib/api', () => { return api.retryWithBackoff(fn) .then(() => { - console.log('gsd') expect(fn).to.be.calledTwice expect(fn.firstCall.args[0]).eq(0) expect(fn.secondCall.args[0]).eq(1) @@ -1012,19 +1011,19 @@ describe('lib/api', () => { expect(errors.warning).to.be.calledThrice expect(errors.warning.firstCall.args[0]).to.eql('DASHBOARD_API_RESPONSE_FAILED_RETRYING') expect(errors.warning.firstCall.args[1]).to.eql({ - delay: '30 seconds', + delay: 30000, tries: 3, response: err, }) expect(errors.warning.secondCall.args[1]).to.eql({ - delay: '1 minute', + delay: 60000, tries: 2, response: err, }) expect(errors.warning.thirdCall.args[1]).to.eql({ - delay: '2 minutes', + delay: 120000, tries: 1, response: err, }) diff --git a/packages/server/test/unit/browsers/browser-cri-client_spec.ts b/packages/server/test/unit/browsers/browser-cri-client_spec.ts index fa5203f87808..56f84fb98082 100644 --- a/packages/server/test/unit/browsers/browser-cri-client_spec.ts +++ b/packages/server/test/unit/browsers/browser-cri-client_spec.ts @@ -2,6 +2,7 @@ import { BrowserCriClient } from '../../../lib/browsers/browser-cri-client' import * as CriClient from '../../../lib/browsers/cri-client' import { expect, proxyquire, sinon } from '../../spec_helper' import * as protocol from '../../../lib/browsers/protocol' +import { stripAnsi } from '@packages/errors' const HOST = '127.0.0.1' const PORT = 50505 @@ -105,7 +106,9 @@ describe('lib/browsers/cri-client', function () { it('rejects if protocolVersion < current', function () { return expect(withProtocolVersion('1.2', '1.3')).to.be - .rejectedWith('A minimum CDP version of v1.3 is required, but the current browser has v1.2.') + .rejected.then((err) => { + expect(stripAnsi(err.message)).to.eq(`A minimum CDP version of 1.3 is required, but the current browser has 1.2.`) + }) }) }) diff --git a/packages/server/test/unit/browsers/browsers_spec.js b/packages/server/test/unit/browsers/browsers_spec.js index e22d11f8ba52..ccd66d3f8f81 100644 --- a/packages/server/test/unit/browsers/browsers_spec.js +++ b/packages/server/test/unit/browsers/browsers_spec.js @@ -1,6 +1,8 @@ require('../../spec_helper') +const stripAnsi = require('strip-ansi') const os = require('os') +const chalk = require('chalk') const browsers = require(`../../../lib/browsers`) const utils = require(`../../../lib/browsers/utils`) const snapshot = require('snap-shot-it') @@ -9,8 +11,12 @@ const { sinon } = require('../../spec_helper') const { exec } = require('child_process') const util = require('util') +const normalizeSnapshot = (str) => { + return snapshot(stripAnsi(str)) +} + const normalizeBrowsers = (message) => { - return message.replace(/(found on your system are:)(?:\n- .*)*/, '$1\n- chrome\n- firefox\n- electron') + return message.replace(/(found on your system are:)(?:\n - .*)*/, '$1\n - chrome\n - firefox\n - electron') } // When we added component testing mode, we added the option for electron to be omitted @@ -82,7 +88,7 @@ describe('lib/browsers/index', () => { return expect(browsers.ensureAndGetByNameOrPath('browserNotGonnaBeFound', false, foundBrowsers)) .to.be.rejectedWith({ type: 'BROWSER_NOT_FOUND_BY_NAME' }) .then((err) => { - return snapshot(normalizeBrowsers(err.message)) + return normalizeSnapshot(normalizeBrowsers(stripAnsi(err.message))) }) }) @@ -96,13 +102,13 @@ describe('lib/browsers/index', () => { return expect(browsers.ensureAndGetByNameOrPath('canary', false, foundBrowsers)) .to.be.rejectedWith({ type: 'BROWSER_NOT_FOUND_BY_NAME' }) .then((err) => { - return snapshot(err.message) + return normalizeSnapshot(err.message) }) }) }) context('.connectToNewSpec', () => { - it('throws an error if browser family doesn\'t exist', () => { + it(`throws an error if browser family doesn't exist`, () => { return browsers.connectToNewSpec({ name: 'foo-bad-bang', family: 'foo-bad', @@ -111,18 +117,19 @@ describe('lib/browsers/index', () => { }) .then((e) => { throw new Error('should\'ve failed') - }).catch((err) => { + }) + .catch((err) => { // by being explicit with assertions, if something is unexpected // we will get good error message that includes the "err" object expect(err).to.have.property('type').to.eq('BROWSER_NOT_FOUND_BY_NAME') - expect(err).to.have.property('message').to.contain('The specified browser was not found on your system or is not supported by Cypress: `foo-bad-bang`') + expect(err).to.have.property('message').to.contain(`Browser: ${chalk.yellow('foo-bad-bang')} was not found on your system or is not supported by Cypress.`) }) }) }) context('.open', () => { - it('throws an error if browser family doesn\'t exist', () => { + it(`throws an error if browser family doesn't exist`, () => { return browsers.open({ name: 'foo-bad-bang', family: 'foo-bad', @@ -131,12 +138,13 @@ describe('lib/browsers/index', () => { }) .then((e) => { throw new Error('should\'ve failed') - }).catch((err) => { + }) + .catch((err) => { // by being explicit with assertions, if something is unexpected // we will get good error message that includes the "err" object expect(err).to.have.property('type').to.eq('BROWSER_NOT_FOUND_BY_NAME') - expect(err).to.have.property('message').to.contain('The specified browser was not found on your system or is not supported by Cypress: `foo-bad-bang`') + expect(err).to.have.property('message').to.contain(`Browser: ${chalk.yellow('foo-bad-bang')} was not found on your system`) }) }) }) diff --git a/packages/server/test/unit/browsers/cri-client_spec.ts b/packages/server/test/unit/browsers/cri-client_spec.ts index 0f2842bd04bf..60e3de42309a 100644 --- a/packages/server/test/unit/browsers/cri-client_spec.ts +++ b/packages/server/test/unit/browsers/cri-client_spec.ts @@ -1,6 +1,6 @@ import Bluebird from 'bluebird' -import { create } from '../../../lib/browsers/cri-client' import EventEmitter from 'events' +import { create } from '../../../lib/browsers/cri-client' const { expect, proxyquire, sinon } = require('../../spec_helper') diff --git a/packages/server/test/unit/browsers/firefox_spec.ts b/packages/server/test/unit/browsers/firefox_spec.ts index 1cb0207dc39b..c07ba6d67cea 100644 --- a/packages/server/test/unit/browsers/firefox_spec.ts +++ b/packages/server/test/unit/browsers/firefox_spec.ts @@ -3,10 +3,11 @@ require('../../spec_helper') import 'chai-as-promised' import { expect } from 'chai' import { EventEmitter } from 'events' -import Foxdriver from '@benmalka/foxdriver' import Marionette from 'marionette-client' import os from 'os' import sinon from 'sinon' +import stripAnsi from 'strip-ansi' +import Foxdriver from '@benmalka/foxdriver' import * as firefox from '../../../lib/browsers/firefox' import firefoxUtil from '../../../lib/browsers/firefox-util' @@ -442,7 +443,11 @@ describe('lib/browsers/firefox', () => { } await expect(firefoxUtil.setupMarionette([], '', port)) - .to.be.rejectedWith('An unexpected error was received from Marionette Socket:\n\nError: foo error') + .to.be.rejected.then((err) => { + expect(stripAnsi(err.message)).to.include(`An unexpected error was received from Marionette: Socket`) + expect(err.details).to.include('Error: foo error') + expect(err.originalError.message).to.eq('foo error') + }) }) it('rejects on errors from marionette commands', async () => { @@ -451,14 +456,20 @@ describe('lib/browsers/firefox', () => { } await expect(firefoxUtil.setupMarionette([], '', port)) - .to.be.rejectedWith('An unexpected error was received from Marionette commands:\n\nError: foo error') + .to.be.rejected.then((err) => { + expect(stripAnsi(err.message)).to.include('An unexpected error was received from Marionette: commands') + expect(err.details).to.include('Error: foo error') + }) }) it('rejects on errors during initial Marionette connection', async () => { marionetteDriver.connect.rejects(new Error('not connectable')) await expect(firefoxUtil.setupMarionette([], '', port)) - .to.be.rejectedWith('An unexpected error was received from Marionette connection:\n\nError: not connectable') + .to.be.rejected.then((err) => { + expect(stripAnsi(err.message)).to.include('An unexpected error was received from Marionette: connection') + expect(err.details).to.include('Error: not connectable') + }) }) }) diff --git a/packages/server/test/unit/browsers/protocol_spec.ts b/packages/server/test/unit/browsers/protocol_spec.ts index ddf4eab61589..f398f61be39e 100644 --- a/packages/server/test/unit/browsers/protocol_spec.ts +++ b/packages/server/test/unit/browsers/protocol_spec.ts @@ -1,13 +1,13 @@ import '../../spec_helper' -import _ from 'lodash' -import 'chai-as-promised' -import { connect } from '@packages/network' +import 'chai-as-promised' // for the types! import { expect } from 'chai' import humanInterval from 'human-interval' -import * as protocol from '../../../lib/browsers/protocol' +import _ from 'lodash' import sinon from 'sinon' import snapshot from 'snap-shot-it' import stripAnsi from 'strip-ansi' +import { connect } from '@packages/network' +import * as protocol from '../../../lib/browsers/protocol' describe('lib/browsers/protocol', () => { context('._getDelayMsForRetry', () => { @@ -18,7 +18,7 @@ describe('lib/browsers/protocol', () => { let delay: number let i = 0 - while ((delay = protocol._getDelayMsForRetry(i, 'FooBrowser'))) { + while ((delay = protocol._getDelayMsForRetry(i, 'foobrowser'))) { delays.push(delay) i++ } @@ -28,7 +28,7 @@ describe('lib/browsers/protocol', () => { log.getCalls().forEach((log, i) => { const line = stripAnsi(log.args[0]) - expect(line).to.include(`Still waiting to connect to FooBrowser, retrying in 1 second (attempt ${i + 18}/62)`) + expect(line).to.include(`Still waiting to connect to Foobrowser, retrying in 1 second (attempt ${i + 18}/62)`) }) snapshot(delays) diff --git a/packages/server/test/unit/config_spec.js b/packages/server/test/unit/config_spec.js index 25136fe2efb4..b63a3d379dcd 100644 --- a/packages/server/test/unit/config_spec.js +++ b/packages/server/test/unit/config_spec.js @@ -2,6 +2,8 @@ require('../spec_helper') const _ = require('lodash') const debug = require('debug')('test') +const stripAnsi = require('strip-ansi') +const { stripIndent } = require('common-tags') const Fixtures = require('@tooling/system-tests/lib/fixtures') const { getCtx } = require('@packages/data-context') @@ -24,7 +26,7 @@ describe('lib/config', () => { context('environment name check', () => { it('throws an error for unknown CYPRESS_INTERNAL_ENV', () => { - sinon.stub(errors, 'throw').withArgs('INVALID_CYPRESS_INTERNAL_ENV', 'foo-bar') + sinon.stub(errors, 'throwErr').withArgs('INVALID_CYPRESS_INTERNAL_ENV', 'foo-bar') process.env.CYPRESS_INTERNAL_ENV = 'foo-bar' const cfg = { projectRoot: '/foo/bar/', @@ -37,11 +39,11 @@ describe('lib/config', () => { // } - expect(errors.throw).have.been.calledOnce + expect(errors.throwErr).have.been.calledOnce }) it('allows production CYPRESS_INTERNAL_ENV', () => { - sinon.stub(errors, 'throw') + sinon.stub(errors, 'throwErr') process.env.CYPRESS_INTERNAL_ENV = 'production' const cfg = { projectRoot: '/foo/bar/', @@ -50,7 +52,7 @@ describe('lib/config', () => { config.mergeDefaults(cfg, options) - expect(errors.throw).not.to.be.called + expect(errors.throwErr).not.to.be.called }) }) @@ -140,7 +142,7 @@ describe('lib/config', () => { .then(() => { throw new Error('should throw validation error') }).catch((err) => { - expect(err.message).to.include(errorMessage) + expect(stripAnsi(err.message)).to.include(stripIndent`${errorMessage}`) }) } }) @@ -180,9 +182,17 @@ describe('lib/config', () => { it('fails if not a number', function () { this.setup({ animationDistanceThreshold: { foo: 'bar' } }) - this.expectValidationFails('be a number') - return this.expectValidationFails('the value was: \`{"foo":"bar"}\`') + return this.expectValidationFails('be a number') + .then(() => { + return this.expectValidationFails(` + the value was: \ + + + { + "foo": "bar" + }`) + }) }) }) @@ -214,7 +224,7 @@ describe('lib/config', () => { it('fails if it is set on root level', function () { this.setup({ baseUrl: 'localhost' }) - return this.expectValidationFails('Please update this option under e2e testing type property') + return this.expectValidationFails('It is now configured separately as a testing type property: e2e.baseUrl') }) }) @@ -227,9 +237,11 @@ describe('lib/config', () => { it('fails if not a boolean', function () { this.setup({ chromeWebSecurity: 42 }) - this.expectValidationFails('be a boolean') - return this.expectValidationFails('the value was: `42`') + return this.expectValidationFails('be a boolean') + .then(() => { + return this.expectValidationFails('the value was: 42') + }) }) }) @@ -242,9 +254,11 @@ describe('lib/config', () => { it('fails if not a boolean', function () { this.setup({ modifyObstructiveCode: 42 }) - this.expectValidationFails('be a boolean') - return this.expectValidationFails('the value was: `42`') + return this.expectValidationFails('be a boolean') + .then(() => { + return this.expectValidationFails('the value was: 42') + }) }) }) @@ -261,16 +275,20 @@ describe('lib/config', () => { it('fails if not a plain object', function () { this.setup({ component: false }) - this.expectValidationFails('to be a plain object') - return this.expectValidationFails('the value was: `false`') + return this.expectValidationFails('to be a plain object') + .then(() => { + return this.expectValidationFails('the value was: false') + }) }) it('fails if nested property is incorrect', function () { this.setup({ component: { baseUrl: false } }) - this.expectValidationFails('Expected `component.baseUrl` to be a fully qualified URL (starting with `http://` or `https://`).') - return this.expectValidationFails('the value was: `false`') + return this.expectValidationFails('Expected component.baseUrl to be a fully qualified URL (starting with `http://` or `https://`).') + .then(() => { + return this.expectValidationFails('the value was: false') + }) }) }) @@ -286,23 +304,29 @@ describe('lib/config', () => { it('fails if not a plain object', function () { this.setup({ e2e: false }) - this.expectValidationFails('to be a plain object') - return this.expectValidationFails('the value was: `false`') + return this.expectValidationFails('to be a plain object') + .then(() => { + return this.expectValidationFails('the value was: false') + }) }) it('fails if nested property is incorrect', function () { this.setup({ e2e: { animationDistanceThreshold: 'this is definitely not a number' } }) - this.expectValidationFails('Expected `e2e.animationDistanceThreshold` to be a number') - return this.expectValidationFails('the value was: `"this is definitely not a number"`') + return this.expectValidationFails('Expected e2e.animationDistanceThreshold to be a number') + .then(() => { + return this.expectValidationFails('the value was: "this is definitely not a number"') + }) }) it('fails if nested property is incorrect', function () { this.setup({ component: { baseUrl: false } }) - this.expectValidationFails('Expected `component.baseUrl` to be a fully qualified URL (starting with `http://` or `https://`).') - return this.expectValidationFails('the value was: `false`') + return this.expectValidationFails('Expected component.baseUrl to be a fully qualified URL (starting with `http://` or `https://`).') + .then(() => { + return this.expectValidationFails('the value was: false') + }) }) }) @@ -315,9 +339,11 @@ describe('lib/config', () => { it('fails if not a number', function () { this.setup({ defaultCommandTimeout: 'foo' }) - this.expectValidationFails('be a number') - return this.expectValidationFails('the value was: `"foo"`') + return this.expectValidationFails('be a number') + .then(() => { + return this.expectValidationFails('the value was: "foo"') + }) }) }) @@ -372,9 +398,11 @@ describe('lib/config', () => { it('fails if not a string', function () { this.setup({ fileServerFolder: true }) - this.expectValidationFails('be a string') - return this.expectValidationFails('the value was: `true`') + return this.expectValidationFails('be a string') + .then(() => { + return this.expectValidationFails('the value was: true') + }) }) }) @@ -419,9 +447,17 @@ describe('lib/config', () => { it('fails if not an array of strings', function () { this.setup({ e2e: { excludeSpecPattern: [5] } }) - this.expectValidationFails('be a string or an array of strings') - return this.expectValidationFails('the value was: `[5]`') + return this.expectValidationFails('be a string or an array of strings') + .then(() => { + return this.expectValidationFails(` + the value was: \ + + + [ + 5 + ]`) + }) }) }) @@ -557,8 +593,8 @@ describe('lib/config', () => { }) }) - // TODO(lachlan): after mega PR - xcontext('specPattern', () => { + // TODO:(lachlan): after mega PR + context.skip('specPattern', () => { it('passes if a string', function () { this.setup({ e2e: { specPattern: '**/*.coffee' } }) @@ -579,9 +615,17 @@ describe('lib/config', () => { it('fails if not an array of strings', function () { this.setup({ e2e: { specPattern: [5] } }) - this.expectValidationFails('be a string or an array of strings') - return this.expectValidationFails('the value was: `[5]`') + return this.expectValidationFails('be a string or an array of strings') + .then(() => { + return this.expectValidationFails(` + the value was: \ + + + [ + 5 + ]`) + }) }) }) @@ -601,7 +645,10 @@ describe('lib/config', () => { it('fails if is set at root level', function () { this.setup({ supportFile: false }) - return this.expectValidationFails('was removed from the root in Cypress version `10.0.0`') + return this.expectValidationFails('The supportFile configuration option is now invalid when set from the root of the config object in') + .then(() => { + return this.expectValidationFails('It is now configured separately as a testing type property: e2e.supportFile and component.supportFile') + }) }) }) @@ -822,9 +869,17 @@ describe('lib/config', () => { it('fails if not an array of strings', function () { this.setup({ blockHosts: [5] }) - this.expectValidationFails('be a string or an array of strings') - return this.expectValidationFails('the value was: `[5]`') + return this.expectValidationFails('be a string or an array of strings') + .then(() => { + return this.expectValidationFails(` + the value was: \ + + + [ + 5 + ]`) + }) }) }) @@ -910,7 +965,7 @@ describe('lib/config', () => { cfg.clientCertificates[0].url = null this.setup(cfg) - return this.expectValidationFails('`clientCertificates[0].url` to be a URL matcher') + return this.expectValidationFails('clientCertificates[0].url to be a URL matcher.\n\nInstead the value was: null') }) it('detects invalid config with no certs', function () { @@ -919,7 +974,7 @@ describe('lib/config', () => { cfg.clientCertificates[0].certs = null this.setup(cfg) - return this.expectValidationFails('`clientCertificates[0].certs` to be an array of certs') + return this.expectValidationFails('clientCertificates[0].certs to be an array of certs.\n\nInstead the value was: null') }) it('detects invalid config with no cert', function () { @@ -946,7 +1001,7 @@ describe('lib/config', () => { cfg.clientCertificates[0].certs[0].key = null this.setup(cfg) - return this.expectValidationFails('`clientCertificates[0].certs[0].key` to be a key filepath') + return this.expectValidationFails('clientCertificates[0].certs[0].key to be a key filepath.\n\nInstead the value was: null') }) it('detects PEM cert absolute path', function () { @@ -955,7 +1010,7 @@ describe('lib/config', () => { cfg.clientCertificates[0].certs[0].cert = '/home/files/a_file' this.setup(cfg) - return this.expectValidationFails('`clientCertificates[0].certs[0].cert` to be a relative filepath') + return this.expectValidationFails('clientCertificates[0].certs[0].cert to be a relative filepath.\n\nInstead the value was: "/home/files/a_file"') }) it('detects PEM key absolute path', function () { @@ -964,7 +1019,7 @@ describe('lib/config', () => { cfg.clientCertificates[0].certs[0].key = '/home/files/a_file' this.setup(cfg) - return this.expectValidationFails('`clientCertificates[0].certs[0].key` to be a relative filepath') + return this.expectValidationFails('clientCertificates[0].certs[0].key to be a relative filepath.\n\nInstead the value was: "/home/files/a_file"') }) it('detects PFX absolute path', function () { @@ -974,7 +1029,7 @@ describe('lib/config', () => { cfg.clientCertificates[0].certs[0].pfx = '/home/files/a_file' this.setup(cfg) - return this.expectValidationFails('`clientCertificates[0].certs[0].pfx` to be a relative filepath') + return this.expectValidationFails('clientCertificates[0].certs[0].pfx to be a relative filepath.\n\nInstead the value was: "/home/files/a_file"') }) it('detects CA absolute path', function () { @@ -983,7 +1038,7 @@ describe('lib/config', () => { cfg.clientCertificates[0].ca[0] = '/home/files/a_file' this.setup(cfg) - return this.expectValidationFails('`clientCertificates[0].ca[0]` to be a relative filepath') + return this.expectValidationFails('clientCertificates[0].ca[0] to be a relative filepath.\n\nInstead the value was: "/home/files/a_file"') }) }) }) @@ -1407,8 +1462,8 @@ describe('lib/config', () => { expect(warning).to.be.calledWith('FIREFOX_GC_INTERVAL_REMOVED') }) - // todo(lachlan): after mega PR - xdescribe('.resolved', () => { + // TODO:(lachlan) after mega PR + describe.skip('.resolved', () => { it('sets reporter and port to cli', () => { const obj = { projectRoot: '/foo/bar', @@ -1819,6 +1874,8 @@ describe('lib/config', () => { } const cfg = { + projectRoot: '/foo/bar', + pluginsFile: '/foo/bar/cypress/plugins/index.js', browsers: [browser], resolved: { browsers: { @@ -1832,10 +1889,10 @@ describe('lib/config', () => { browsers: null, } - sinon.stub(errors, 'throw') + sinon.stub(errors, 'throwErr') config.updateWithPluginValues(cfg, overrides) - expect(errors.throw).to.have.been.calledWith('CONFIG_VALIDATION_ERROR') + expect(errors.throwErr).to.have.been.calledWith('CONFIG_VALIDATION_MSG_ERROR') }) it('allows user to filter browsers', () => { @@ -2080,7 +2137,7 @@ describe('lib/config', () => { return config.setSupportFileAndFolder(obj, mockSupportDefaults) .catch((err) => { - expect(err.message).to.include('The support file is missing or invalid.') + expect(stripAnsi(err.message)).to.include('Your supportFile is missing or invalid:') }) }) diff --git a/packages/server/test/unit/errors_spec.js b/packages/server/test/unit/errors_spec.js index f71134a8b031..b1464d201bca 100644 --- a/packages/server/test/unit/errors_spec.js +++ b/packages/server/test/unit/errors_spec.js @@ -1,188 +1,65 @@ require('../spec_helper') -const style = require('ansi-styles') -const chalk = require('chalk') -const errors = require(`../../lib/errors`) const exception = require(`../../lib/exception`) -const snapshot = require('snap-shot-it') +const chalk = require('chalk') +const errors = require('../../lib/errors') -describe('lib/errors', () => { +context('.logException', () => { beforeEach(() => { - return sinon.spy(console, 'log') + sinon.stub(console, 'log') }) - context('.log', () => { - it('uses red by default', () => { - const err = errors.get('NOT_LOGGED_IN') - - const ret = errors.log(err) - - expect(ret).to.be.undefined - - const { - red, - } = style - - expect(console.log).to.be.calledWithMatch(red.open) - - expect(console.log).to.be.calledWithMatch(red.close) - }) - - it('can change the color', () => { - const err = errors.get('NOT_LOGGED_IN') - - const ret = errors.log(err, 'yellow') - - expect(ret).to.be.undefined - - const { - yellow, - } = style - - expect(console.log).to.be.calledWithMatch(yellow.open) - - expect(console.log).to.be.calledWithMatch(yellow.close) - }) - - it('logs err.message', () => { - const err = errors.get('NO_PROJECT_ID', 'foo/bar/baz') - - const ret = errors.log(err) - - expect(ret).to.be.undefined - - expect(console.log).to.be.calledWithMatch('foo/bar/baz') - }) - - it('converts markdown links in err.message', () => { - const err = errors.get('NO_PROJECT_ID', ` - This line has [linked text](https://on.cypress.io) in it. There's a period in the middle. - - This line has [linked text at the end](https://on.cypress.io). - - This line has [linked text](https://on.cypress.io) with no period - `) - - errors.log(err) + it('calls exception.create with unknown error', () => { + sinon.stub(exception, 'create').resolves() + sinon.stub(process.env, 'CYPRESS_INTERNAL_ENV').value('production') - expect(console.log).to.be.calledWithMatch('This line has linked text in it. There\'s a period in the middle: https://on.cypress.io') - expect(console.log).to.be.calledWithMatch('This line has linked text at the end: https://on.cypress.io') - expect(console.log).to.be.calledWithMatch('This line has linked text with no period: https://on.cypress.io') - }) - - it('logs err.details', () => { - const err = errors.get('PLUGINS_FUNCTION_ERROR', 'foo/bar/baz', 'details huh') - - const ret = errors.log(err) - - expect(ret).to.be.undefined - - expect(console.log).to.be.calledWithMatch('foo/bar/baz') - - expect(console.log).to.be.calledWithMatch('\n', 'details huh') - }) - - it('logs err.stack in development', () => { - process.env.CYPRESS_INTERNAL_ENV = 'development' - - const err = new Error('foo') - - const ret = errors.log(err) + const err = new Error('foo') - expect(ret).to.eq(err) + return errors.logException(err) + .then(() => { + expect(console.log).to.be.calledWith(chalk.red(err.stack ?? '')) - expect(console.log).to.be.calledWith(chalk.red(err.stack)) + expect(exception.create).to.be.calledWith(err) }) }) - context('.logException', () => { - it('calls exception.create with unknown error', () => { - sinon.stub(exception, 'create').resolves() - sinon.stub(process.env, 'CYPRESS_INTERNAL_ENV').value('production') + it('does not call exception.create when known error', () => { + sinon.stub(exception, 'create').resolves() + sinon.stub(process.env, 'CYPRESS_INTERNAL_ENV').value('production') - const err = new Error('foo') + const err = errors.get('NOT_LOGGED_IN') - return errors.logException(err) - .then(() => { - expect(console.log).to.be.calledWith(chalk.red(err.stack)) + return errors.logException(err) + .then(() => { + expect(console.log).not.to.be.calledWith(err.stack) - expect(exception.create).to.be.calledWith(err) - }) + expect(exception.create).not.to.be.called }) + }) - it('does not call exception.create when known error', () => { - sinon.stub(exception, 'create').resolves() - sinon.stub(process.env, 'CYPRESS_INTERNAL_ENV').value('production') - - const err = errors.get('NOT_LOGGED_IN') - - return errors.logException(err) - .then(() => { - expect(console.log).not.to.be.calledWith(err.stack) - - expect(exception.create).not.to.be.called - }) - }) - - it('does not call exception.create when not in production env', () => { - sinon.stub(exception, 'create').resolves() - sinon.stub(process.env, 'CYPRESS_INTERNAL_ENV').value('development') - - const err = new Error('foo') - - return errors.logException(err) - .then(() => { - expect(console.log).not.to.be.calledWith(err.stack) - - expect(exception.create).not.to.be.called - }) - }) + it('does not call exception.create when not in production env', () => { + sinon.stub(exception, 'create').resolves() + sinon.stub(process.env, 'CYPRESS_INTERNAL_ENV').value('development') - it('swallows creating exception errors', () => { - sinon.stub(exception, 'create').rejects(new Error('foo')) - sinon.stub(process.env, 'CYPRESS_INTERNAL_ENV').value('production') + const err = new Error('foo') - const err = errors.get('NOT_LOGGED_IN') + return errors.logException(err) + .then(() => { + expect(console.log).not.to.be.calledWith(err.stack) - return errors.logException(err) - .then((ret) => { - expect(ret).to.be.undefined - }) + expect(exception.create).not.to.be.called }) }) - context('.clone', () => { - it('converts err.message from ansi to html with span classes when html true', () => { - const err = new Error(`foo${chalk.blue('bar')}${chalk.yellow('baz')}`) - const obj = errors.clone(err, { html: true }) + it('swallows creating exception errors', () => { + sinon.stub(exception, 'create').rejects(new Error('foo')) + sinon.stub(process.env, 'CYPRESS_INTERNAL_ENV').value('production') - expect(obj.message).to.eq('foobarbaz') - }) - - it('does not convert err.message from ansi to html when no html option', () => { - const err = new Error(`foo${chalk.blue('bar')}${chalk.yellow('baz')}`) - const obj = errors.clone(err) - - expect(obj.message).to.eq('foo\u001b[34mbar\u001b[39m\u001b[33mbaz\u001b[39m') - }) - }) + const err = errors.get('NOT_LOGGED_IN') - context('.displayFlags', () => { - it('returns string formatted from selected keys', () => { - const options = { - tags: 'nightly,staging', - name: 'my tests', - unused: 'some other value', - } - // we are only interested in showig tags and name values - // and prepending them with custom prefixes - const mapping = { - tags: '--tag', - name: '--name', - } - const text = errors.displayFlags(options, mapping) - - return snapshot('tags and name only', text) + return errors.logException(err) + .then((ret) => { + expect(ret).to.be.undefined }) }) }) diff --git a/packages/server/test/unit/gui/events_spec.js b/packages/server/test/unit/gui/events_spec.js index b4b0e3aa6135..feda29ddd36f 100644 --- a/packages/server/test/unit/gui/events_spec.js +++ b/packages/server/test/unit/gui/events_spec.js @@ -46,7 +46,7 @@ describe('lib/gui/events', () => { expect(this.send).to.be.calledWith('response', { id, data }) }, sendErrCalledWith: (err) => { - expect(this.send).to.be.calledWith('response', { id, __error: errors.clone(err, { html: true }) }) + expect(this.send).to.be.calledWith('response', { id, __error: errors.cloneErr(err, { html: true }) }) }, }) } @@ -60,7 +60,8 @@ describe('lib/gui/events', () => { }) }) - xcontext('.start', () => { + // TODO:(tgriesser) originally skipped this, not sure why + context.skip('.start', () => { it('ipc attaches callback on request', () => { sinon.stub(events, 'handleEvent') diff --git a/packages/server/test/unit/modes/record_spec.js b/packages/server/test/unit/modes/record_spec.js index 26c71d36ba1a..645fad3501b6 100644 --- a/packages/server/test/unit/modes/record_spec.js +++ b/packages/server/test/unit/modes/record_spec.js @@ -451,13 +451,13 @@ describe('lib/modes/record', () => { api.createRun.rejects(err) - sinon.spy(errors, 'throw') + sinon.spy(errors, 'throwErr') await expect(recordMode.createRun({ git: {}, recordKey: true, // instead of a string })).to.be.rejected - expect(errors.throw).to.have.been.calledWith('DASHBOARD_RECORD_KEY_NOT_VALID', 'undefined') + expect(errors.throwErr).to.have.been.calledWith('DASHBOARD_RECORD_KEY_NOT_VALID', 'undefined') }) }) diff --git a/packages/server/test/unit/plugins/child/run_plugins_spec.js b/packages/server/test/unit/plugins/child/run_plugins_spec.js index da3bca02d0bc..1081a85617e3 100644 --- a/packages/server/test/unit/plugins/child/run_plugins_spec.js +++ b/packages/server/test/unit/plugins/child/run_plugins_spec.js @@ -1,15 +1,19 @@ require('../../../spec_helper') const _ = require('lodash') +const snapshot = require('snap-shot-it') const Promise = require('bluebird') const preprocessor = require(`../../../../lib/plugins/child/preprocessor`) const util = require(`../../../../lib/plugins/util`) const resolve = require(`../../../../lib/util/resolve`) const browserUtils = require(`../../../../lib/browsers/utils`) - +const Fixtures = require('@tooling/system-tests/lib/fixtures') const { RunPlugins } = require(`../../../../lib/plugins/child/run_plugins`) +const colorCodeRe = /\[[0-9;]+m/gm +const pathRe = /\/?([a-z0-9_-]+\/)*[a-z0-9_-]+\/([a-z_]+\.\w+)[:0-9]+/gmi + const deferred = () => { let reject let resolve @@ -21,6 +25,13 @@ const deferred = () => { return { promise, resolve, reject } } +const withoutColorCodes = (str) => { + return str.replace(colorCodeRe, '') +} +const withoutPath = (str) => { + return str.replace(pathRe, '$2)') +} + // TODO: tim, come back to this later describe.skip('lib/plugins/child/run_plugins', () => { let runPlugins @@ -39,6 +50,25 @@ describe.skip('lib/plugins/child/run_plugins', () => { mockery.deregisterMock('@cypress/webpack-batteries-included-preprocessor') }) + it('sends error message if configFile has syntax error', function () { + // path for substitute is relative to lib/plugins/child/plugins_child.js + mockery.registerSubstitute( + 'plugins-file', + Fixtures.path('server/syntax_error.js'), + ) + + runPlugins(this.ipc, 'plugins-file', 'proj-root') + expect(this.ipc.send).to.be.calledWith('load:error', 'PLUGINS_FILE_ERROR', 'plugins-file') + + return snapshot(withoutColorCodes(withoutPath(this.ipc.send.lastCall.args[3].stack.replace(/( +at[^$]+$)+/g, '[stack trace]')))) + }) + + it('sends error message if setupNodeEvents does not export a function', function () { + mockery.registerMock('plugins-file', null) + runPlugins(this.ipc, 'plugins-file', 'proj-root') + expect(this.ipc.send).to.be.calledWith('load:error', 'SETUP_NODE_EVENTS_IS_NOT_FUNCTION', 'plugins-file') + }) + it('sends error message if setupNodeEvents is not a function', function () { const config = { projectRoot: '/project/root' } @@ -193,10 +223,11 @@ describe.skip('lib/plugins/child/run_plugins', () => { this.ipc.on.withArgs('load:plugins').yields({}) runPlugins.runSetupNodeEvents(setupNodeEventsFn) - this.ipc.send = _.once((event, errorType, stack) => { + this.ipc.send = _.once((event, errorType, pluginsFile, result) => { expect(event).to.eq('setupTestingType:error') - expect(errorType).to.eq('PLUGINS_FUNCTION_ERROR') - expect(stack).to.eq(err.stack) + expect(errorType).to.eq('CHILD_PROCESS_UNEXPECTED_ERROR') + expect(pluginsFile).to.eq('plugins-file') + expect(result.stack).to.eq(err.stack) return done() }) @@ -227,10 +258,11 @@ describe.skip('lib/plugins/child/run_plugins', () => { this.ipc.on.withArgs('load:plugins').yield({}) - this.ipc.send = _.once((event, errorType, stack) => { + this.ipc.send = _.once((event, errorType, pluginsFile, serializedErr) => { expect(event).to.eq('setupTestingType:error') - expect(errorType).to.eq('PLUGINS_FUNCTION_ERROR') - expect(stack).to.eq(err.stack) + expect(errorType).to.eq('CHILD_PROCESS_UNEXPECTED_ERROR') + expect(pluginsFile).to.eq('plugins-file') + expect(serializedErr.stack).to.eq(err.stack) return done() }) @@ -403,7 +435,7 @@ describe.skip('lib/plugins/child/run_plugins', () => { expect(result).to.equal('result') }) - it('returns __cypress_unhandled__ if the task doesn\'t exist', function () { + it(`returns __cypress_unhandled__ if the task doesn't exist`, function () { runPlugins.taskExecute(this.ids, ['nope']) expect(util.wrapChildPromise.lastCall.args[1]('1')).to.equal('__cypress_unhandled__') diff --git a/packages/server/test/unit/plugins/child/run_require_async_child_spec.js b/packages/server/test/unit/plugins/child/run_require_async_child_spec.js index f96699507999..ca0b332fd164 100644 --- a/packages/server/test/unit/plugins/child/run_require_async_child_spec.js +++ b/packages/server/test/unit/plugins/child/run_require_async_child_spec.js @@ -54,7 +54,7 @@ describe('lib/plugins/child/run_require_async_child', () => { it('sends the serialized error via ipc on process uncaughtException', function () { process.on.withArgs('uncaughtException').yield(this.err) - expect(this.ipc.send).to.be.calledWith('setupTestingType:uncaughtError', this.err) + expect(this.ipc.send).to.be.calledWith('childProcess:unhandledError', this.err) }) it('sends the serialized error via ipc on process unhandledRejection', function () { diff --git a/packages/server/test/unit/plugins/child/validate_event_spec.js b/packages/server/test/unit/plugins/child/validate_event_spec.js index c58ead318a86..dee6e85a0727 100644 --- a/packages/server/test/unit/plugins/child/validate_event_spec.js +++ b/packages/server/test/unit/plugins/child/validate_event_spec.js @@ -20,27 +20,15 @@ describe('lib/plugins/child/validate_event', () => { const { isValid, error } = validateEvent() expect(isValid).to.be.false - expect(error.message).to.equal(`You must pass a valid event name when registering a plugin. - -You passed: \`undefined\` - -The following are valid events: -- after:run -- after:screenshot -- after:spec -- before:browser:launch -- before:run -- before:spec -- dev-server:start -- file:preprocessor -- task -`) + expect(error.name).to.equal('InvalidEventNameError') + expect(error.message).to.equal(`invalid event name registered: undefined`) }) it('returns error when called with no event handler', () => { const { isValid, error } = validateEvent('file:preprocessor') expect(isValid).to.be.false + expect(error.name).to.equal('InvalidEventHandlerError') expect(error.message).to.equal('The handler for the event `file:preprocessor` must be a function') }) @@ -48,21 +36,8 @@ The following are valid events: const { isValid, error } = validateEvent('invalid:event:name', {}) expect(isValid).to.be.false - expect(error.message).to.equal(`You must pass a valid event name when registering a plugin. - -You passed: \`invalid:event:name\` - -The following are valid events: -- after:run -- after:screenshot -- after:spec -- before:browser:launch -- before:run -- before:spec -- dev-server:start -- file:preprocessor -- task -`) + expect(error.name).to.equal('InvalidEventNameError') + expect(error.message).to.equal(`invalid event name registered: invalid:event:name`) }) _.each(events, ([event, type]) => { @@ -70,6 +45,7 @@ The following are valid events: const { isValid, error } = validateEvent(event, 'invalid type') expect(isValid).to.be.false + expect(error.name).to.equal('InvalidEventHandlerError') expect(error.message).to.equal(`The handler for the event \`${event}\` must be ${type}`) }) }) diff --git a/packages/server/test/unit/plugins/index_spec.js b/packages/server/test/unit/plugins/index_spec.js index 044528391b10..af21f40d4e7f 100644 --- a/packages/server/test/unit/plugins/index_spec.js +++ b/packages/server/test/unit/plugins/index_spec.js @@ -1,3 +1,5 @@ +const stripAnsi = require('strip-ansi') + require('../../spec_helper') const mockedEnv = require('mocked-env') @@ -210,13 +212,16 @@ describe.skip('lib/plugins/index', () => { describe('load:error message', () => { context('PLUGINS_FILE_ERROR', () => { beforeEach(() => { - ipc.on.withArgs('load:error').yields('PLUGINS_FILE_ERROR', 'path/to/pluginsFile.js', 'error message stack') + const e = new Error('some error') + + e.stack = 'error message stack' + ipc.on.withArgs('load:error').yields('PLUGINS_FILE_ERROR', 'path/to/pluginsFile.js', e) }) it('rejects plugins.init', () => { return plugins.init({ pluginsFile: 'cypress-plugin' }, getOptions()) .catch((err) => { - expect(err.message).to.contain('The plugins file is missing or invalid') + expect(stripAnsi(err.message)).to.contain('Your pluginsFile is invalid') expect(err.message).to.contain('path/to/pluginsFile.js') expect(err.details).to.contain('error message stack') @@ -226,13 +231,16 @@ describe.skip('lib/plugins/index', () => { context('PLUGINS_FUNCTION_ERROR', () => { beforeEach(() => { - ipc.on.withArgs('load:error').yields('PLUGINS_FUNCTION_ERROR', 'path/to/pluginsFile.js', 'error message stack') + const e = new Error() + + e.stack = 'error message stack' + ipc.on.withArgs('load:error').yields('PLUGINS_FUNCTION_ERROR', 'path/to/pluginsFile.js', e) }) it('rejects plugins.init', () => { return plugins.init({ pluginsFile: 'cypress-plugin' }, getOptions()) .catch((err) => { - expect(err.message).to.contain('The function exported by the plugins file threw an error.') + expect(stripAnsi(err.message)).to.contain('Your pluginsFile threw an error from:') expect(err.message).to.contain('path/to/pluginsFile.js') expect(err.details).to.contain('error message stack') @@ -249,6 +257,7 @@ describe.skip('lib/plugins/index', () => { err = { name: 'error name', message: 'error message', + stack: 'error stack', } onError = sinon.spy() @@ -272,19 +281,19 @@ describe.skip('lib/plugins/index', () => { it('calls onError when plugins process errors', () => { pluginsProcess.on.withArgs('error').yield(err) expect(onError).to.be.called - expect(onError.lastCall.args[0].title).to.equal('Error running plugin') - expect(onError.lastCall.args[0].stack).to.include('The following error was thrown by a plugin') + expect(onError.lastCall.args[0].title).to.equal('Config process error') + expect(stripAnsi(onError.lastCall.args[0].message)).to.include('Your pluginsFile threw an error from:') - expect(onError.lastCall.args[0].details).to.include(err.message) + expect(onError.lastCall.args[0].details).to.include(err.stack) }) it('calls onError when ipc sends error', () => { ipc.on.withArgs('error').yield(err) expect(onError).to.be.called - expect(onError.lastCall.args[0].title).to.equal('Error running plugin') - expect(onError.lastCall.args[0].stack).to.include('The following error was thrown by a plugin') + expect(onError.lastCall.args[0].title).to.equal('Config process error') + expect(stripAnsi(onError.lastCall.args[0].message)).to.include('Your pluginsFile threw an error from:') - expect(onError.lastCall.args[0].details).to.include(err.message) + expect(onError.lastCall.args[0].details).to.include(err.stack) }) }) @@ -295,6 +304,7 @@ describe.skip('lib/plugins/index', () => { err = { name: 'error name', message: 'error message', + stack: 'error stack', } pluginsProcess.on.withArgs('error').yields(err) @@ -306,9 +316,9 @@ describe.skip('lib/plugins/index', () => { throw new Error('Should not resolve') }) .catch((_err) => { - expect(_err.title).to.equal('Error running plugin') - expect(_err.stack).to.include('The following error was thrown by a plugin') - expect(_err.details).to.include(err.message) + expect(_err.title).to.equal('Config process error') + expect(stripAnsi(_err.message)).to.include('Your pluginsFile threw an error from:') + expect(_err.details).to.include(err.stack) }) }) @@ -318,9 +328,9 @@ describe.skip('lib/plugins/index', () => { throw new Error('Should not resolve') }) .catch((_err) => { - expect(_err.title).to.equal('Error running plugin') - expect(_err.stack).to.include('The following error was thrown by a plugin') - expect(_err.details).to.include(err.message) + expect(_err.title).to.equal('Config process error') + expect(stripAnsi(_err.message)).to.include('Your pluginsFile threw an error from:') + expect(_err.details).to.include(err.stack) }) }) }) diff --git a/packages/server/test/unit/plugins/run_events_spec.js b/packages/server/test/unit/plugins/run_events_spec.js index 57346c195c24..b9d9c2b34f15 100644 --- a/packages/server/test/unit/plugins/run_events_spec.js +++ b/packages/server/test/unit/plugins/run_events_spec.js @@ -9,7 +9,7 @@ describe('lib/plugins/run_events', () => { beforeEach(() => { sinon.stub(plugins, 'execute') sinon.stub(plugins, 'has').returns(false) - sinon.stub(errors, 'throw') + sinon.stub(errors, 'throwErr') }) it('returns a promise noop if event is not registered', () => { @@ -41,11 +41,11 @@ describe('lib/plugins/run_events', () => { it('throws custom error if plugins.execute errors', () => { plugins.has.returns(true) - plugins.execute.rejects({ stack: 'The event threw an error' }) + plugins.execute.rejects({ name: 'Error', message: 'The event threw an error', stack: 'stack trace' }) return runEvents.execute('before:spec', {}, 'arg1', 'arg2') .then(() => { - expect(errors.throw).to.be.calledWith('PLUGINS_RUN_EVENT_ERROR', 'before:spec', 'The event threw an error') + expect(errors.throwErr).to.be.calledWith('PLUGINS_RUN_EVENT_ERROR', 'before:spec', { name: 'Error', message: 'The event threw an error', stack: 'stack trace' }) }) }) }) diff --git a/packages/server/test/unit/project_spec.js b/packages/server/test/unit/project_spec.js index 36c59c2d49b8..e7d4efbf530c 100644 --- a/packages/server/test/unit/project_spec.js +++ b/packages/server/test/unit/project_spec.js @@ -1,3 +1,5 @@ +const { theme } = require('@packages/errors') + require('../spec_helper') const path = require('path') @@ -210,7 +212,7 @@ describe.skip('lib/project-base', () => { family: 'some-other-family', name: 'some-other-name', warning: `\ -Your project has set the configuration option: \`chromeWebSecurity: false\` +Your project has set the configuration option: ${theme.yellow('chromeWebSecurity')} to ${theme.blue('false')} This option will not have an effect in Some-other-name. Tests that rely on web security being disabled will not run as expected.\ `, diff --git a/packages/server/test/unit/project_utils_spec.ts b/packages/server/test/unit/project_utils_spec.ts index 2d4c830b7699..0d0121d16d78 100644 --- a/packages/server/test/unit/project_utils_spec.ts +++ b/packages/server/test/unit/project_utils_spec.ts @@ -2,6 +2,7 @@ import Chai from 'chai' import path from 'path' import { getSpecUrl, checkSupportFile } from '../../lib/project_utils' import Fixtures from '@tooling/system-tests/lib/fixtures' +import stripAnsi from 'strip-ansi' const todosPath = Fixtures.projectPath('todos') @@ -110,7 +111,7 @@ describe('lib/project_utils', () => { supportFile: '/this/file/does/not/exist/foo/bar/cypress/support/e2e.js', }) } catch (e) { - expect(e.message).to.include('The support file is missing or invalid.') + expect(stripAnsi(e.message)).to.include('Your supportFile is missing or invalid') } }) }) diff --git a/packages/server/test/unit/server_spec.js b/packages/server/test/unit/server_spec.js index 05dfb1d649c8..d2014f130c7b 100644 --- a/packages/server/test/unit/server_spec.js +++ b/packages/server/test/unit/server_spec.js @@ -39,7 +39,7 @@ describe('lib/server', () => { // TODO: Figure out correct configuration to run these tests and/or which ones we need to keep. // The introducion of server-base/socket-base and the `ensureProp` function made unit testing // the server difficult. -xdescribe('lib/server', () => { +describe.skip('lib/server', () => { beforeEach(function () { this.fileServer = { close () {}, diff --git a/packages/server/test/unit/socket_spec.js b/packages/server/test/unit/socket_spec.js index 06a2192cd4d5..f5de00168a6a 100644 --- a/packages/server/test/unit/socket_spec.js +++ b/packages/server/test/unit/socket_spec.js @@ -482,7 +482,7 @@ describe('lib/socket', () => { sinon.stub(this.options, 'onRequest').rejects(err) return this.client.emit('backend:request', 'http:request', 'foo', (resp) => { - expect(resp.error).to.deep.eq(errors.clone(err)) + expect(resp.error).to.deep.eq(errors.cloneErr(err)) return done() }) diff --git a/packages/server/test/unit/util/args_spec.js b/packages/server/test/unit/util/args_spec.js index 2d1aeabff28c..2a5d565e1297 100644 --- a/packages/server/test/unit/util/args_spec.js +++ b/packages/server/test/unit/util/args_spec.js @@ -710,7 +710,7 @@ describe('lib/util/args', () => { }) }) - it('doesn\'t mess with env vars if Windows registry doesn\'t have proxy', function () { + it(`doesn't mess with env vars if Windows registry doesn't have proxy`, function () { sinon.stub(getWindowsProxyUtil, 'getWindowsProxy').returns() sinon.stub(os, 'platform').returns('win32') const options = this.setup() diff --git a/packages/server/test/unit/util/chrome_policy_check.js b/packages/server/test/unit/util/chrome_policy_check.js index bb0e98c0958d..84b19b363fed 100644 --- a/packages/server/test/unit/util/chrome_policy_check.js +++ b/packages/server/test/unit/util/chrome_policy_check.js @@ -1,3 +1,5 @@ +const stripAnsi = require('strip-ansi') + require('../../spec_helper') const _ = require('lodash') @@ -31,13 +33,13 @@ describe('lib/util/chrome_policy_check', () => { expect(cb).to.be.calledOnce - expect(cb.getCall(0).args[0].message).to.eq(stripIndent(`\ + expect(stripAnsi(cb.getCall(0).args[0].message)).to.eq(stripIndent(`\ Cypress detected policy settings on your computer that may cause issues. The following policies were detected that may prevent Cypress from automating Chrome: - > HKEY_LOCAL_MACHINE\\Software\\Policies\\Google\\Chrome\\ProxyServer - > HKEY_CURRENT_USER\\Software\\Policies\\Google\\Chromium\\ExtensionSettings + - HKEY_LOCAL_MACHINE\\Software\\Policies\\Google\\Chrome\\ProxyServer + - HKEY_CURRENT_USER\\Software\\Policies\\Google\\Chromium\\ExtensionSettings For more information, see https://on.cypress.io/bad-browser-policy\ `)) diff --git a/packages/server/test/unit/util/ensure_url_spec.ts b/packages/server/test/unit/util/ensure_url_spec.ts index 47c8af1904e1..93d8359a3bb4 100644 --- a/packages/server/test/unit/util/ensure_url_spec.ts +++ b/packages/server/test/unit/util/ensure_url_spec.ts @@ -16,7 +16,7 @@ describe('lib/util/ensure-url', function () { }) }) - it('rejects if a URL doesn\'t connect', function () { + it(`rejects if a URL doesn't connect`, function () { const stub = sinon.stub(connect, 'getAddress').withArgs(80, 'foo.bar.invalid').rejects() return isListening('http://foo.bar.invalid') diff --git a/packages/server/test/unit/util/trash_spec.js b/packages/server/test/unit/util/trash_spec.js index fbd1fd480b4f..b09222de3b91 100644 --- a/packages/server/test/unit/util/trash_spec.js +++ b/packages/server/test/unit/util/trash_spec.js @@ -43,7 +43,7 @@ describe('lib/util/trash', () => { }) }) - it('doesn\'t fail if directory is non-existent', () => { + it(`doesn't fail if directory is non-existent`, () => { return trash.folder('bar') .tapCatch(() => { throw new Error('should not have errored') diff --git a/packages/server/tsconfig.json b/packages/server/tsconfig.json index 6ccf4a1085d1..a09cb53762a7 100644 --- a/packages/server/tsconfig.json +++ b/packages/server/tsconfig.json @@ -2,14 +2,18 @@ "extends": "./../ts/tsconfig.json", "include": [ "lib/*.ts", - "lib/**/*.ts" + "lib/**/*.ts", ], "files": [ "./../ts/index.d.ts" ], "compilerOptions": { - "types": ["mocha", "node"], + "types": [ + "mocha", + "node" + ], "resolveJsonModule": true, "noUnusedLocals": false, + "importHelpers": true } -} +} \ No newline at end of file diff --git a/packages/ts/tsconfig.json b/packages/ts/tsconfig.json index 02f06edc79e8..9a1b1089b971 100644 --- a/packages/ts/tsconfig.json +++ b/packages/ts/tsconfig.json @@ -18,6 +18,7 @@ "importHelpers": true, /* Import emit helpers from 'tslib'. */ // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + "useUnknownInCatchVariables": false, /* Strict Type-Checking Options */ "strict": true, /* Enable all strict type-checking options. */ @@ -27,6 +28,8 @@ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ /* Additional Checks */ + + // noUnusedLocals should be linted, not type-check'ed "noUnusedLocals": false, /* Report errors on unused locals. */ "noUnusedParameters": false, /* Report errors on unused parameters. */ "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ diff --git a/packages/types/src/config.ts b/packages/types/src/config.ts index bef12ee623ff..0f33033396dd 100644 --- a/packages/types/src/config.ts +++ b/packages/types/src/config.ts @@ -44,3 +44,26 @@ export interface SettingsOptions { testingType?: 'component' |'e2e' args?: AllModeOptions } + +// Todo, move to @packages/config when it becomes type-safe + +export type BreakingOption = + | 'RENAMED_CONFIG_OPTION' + | 'EXPERIMENTAL_COMPONENT_TESTING_REMOVED' + | 'EXPERIMENTAL_SAMESITE_REMOVED' + | 'EXPERIMENTAL_NETWORK_STUBBING_REMOVED' + | 'EXPERIMENTAL_RUN_EVENTS_REMOVED' + | 'EXPERIMENTAL_SHADOW_DOM_REMOVED' + | 'FIREFOX_GC_INTERVAL_REMOVED' + | 'NODE_VERSION_DEPRECATION_SYSTEM' + | 'NODE_VERSION_DEPRECATION_BUNDLED' + | 'CONFIG_FILE_INVALID_ROOT_CONFIG' + | 'CONFIG_FILE_INVALID_ROOT_CONFIG_E2E' + | 'CONFIG_FILE_INVALID_TESTING_TYPE_CONFIG_COMPONENT' + +export type BreakingErrResult = { + name: string + newName?: string + value?: any + configFile: string +} diff --git a/scripts/gulp/monorepoPaths.ts b/scripts/gulp/monorepoPaths.ts index 93aa8ea32675..75f5bb368947 100644 --- a/scripts/gulp/monorepoPaths.ts +++ b/scripts/gulp/monorepoPaths.ts @@ -9,6 +9,7 @@ export const monorepoPaths = { pkgDataContext: path.join(__dirname, '../../packages/data-context'), pkgDriver: path.join(__dirname, '../../packages/driver'), pkgElectron: path.join(__dirname, '../../packages/electron'), + pkgErrors: path.join(__dirname, '../../packages/errors'), pkgExample: path.join(__dirname, '../../packages/example'), pkgExtension: path.join(__dirname, '../../packages/extension'), pkgFrontendShared: path.join(__dirname, '../../packages/frontend-shared'), diff --git a/scripts/run-if-ci.sh b/scripts/run-if-ci.sh new file mode 100755 index 000000000000..901bf670361c --- /dev/null +++ b/scripts/run-if-ci.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +# If we're in CI, exit early +if [[ $CI == '' ]]; then exit 0; fi +# otherwise, run the supplied command +"${@:1}" diff --git a/system-tests/__snapshots__/browser_path_spec.js b/system-tests/__snapshots__/browser_path_spec.js index 681ae4ece8c3..5a23804b70ca 100644 --- a/system-tests/__snapshots__/browser_path_spec.js +++ b/system-tests/__snapshots__/browser_path_spec.js @@ -7,14 +7,14 @@ exports['e2e launching browsers by path works with an installed browser path 1'] ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Cypress: 1.2.3 │ │ Browser: Custom FooBrowser 88 │ - │ Specs: 1 found (simple.cy.js) │ - │ Searched: cypress/e2e/simple.cy.js │ + │ Specs: 1 found (simple.cy.js) │ + │ Searched: cypress/e2e/simple.cy.js │ └────────────────────────────────────────────────────────────────────────────────────────────────┘ ──────────────────────────────────────────────────────────────────────────────────────────────────── - Running: simple.cy.js (1 of 1) + Running: simple.cy.js (1 of 1) ✓ is true @@ -33,14 +33,14 @@ exports['e2e launching browsers by path works with an installed browser path 1'] │ Screenshots: 0 │ │ Video: true │ │ Duration: X seconds │ - │ Spec Ran: simple.cy.js │ + │ Spec Ran: simple.cy.js │ └────────────────────────────────────────────────────────────────────────────────────────────────┘ (Video) - Started processing: Compressing to 32 CRF - - Finished processing: /XXX/XXX/XXX/cypress/videos/simple.cy.js.mp4 (X second) + - Finished processing: /XXX/XXX/XXX/cypress/videos/simple.cy.js.mp4 (X second) ==================================================================================================== @@ -50,7 +50,7 @@ exports['e2e launching browsers by path works with an installed browser path 1'] Spec Tests Passing Failing Pending Skipped ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ - │ ✔ simple.cy.js XX:XX 1 1 - - - │ + │ ✔ simple.cy.js XX:XX 1 1 - - - │ └────────────────────────────────────────────────────────────────────────────────────────────────┘ ✔ All specs passed! XX:XX 1 1 - - - diff --git a/system-tests/__snapshots__/busted_support_file_spec.js b/system-tests/__snapshots__/busted_support_file_spec.js index c7021b4fbecd..0e4134e98249 100644 --- a/system-tests/__snapshots__/busted_support_file_spec.js +++ b/system-tests/__snapshots__/busted_support_file_spec.js @@ -18,7 +18,7 @@ exports['e2e busted support file passes 1'] = ` Oops...we found an error preparing this test file: - cypress/support/e2e.js + > cypress/support/e2e.js The error was: diff --git a/system-tests/__snapshots__/config_spec.js b/system-tests/__snapshots__/config_spec.js index 0ec2aa0ddf89..60abab8352d0 100644 --- a/system-tests/__snapshots__/config_spec.js +++ b/system-tests/__snapshots__/config_spec.js @@ -141,78 +141,142 @@ exports['e2e config applies defaultCommandTimeout globally 1'] = ` ` exports['e2e config throws error when invalid viewportWidth in the configuration file 1'] = ` -We found an invalid value in the file: \`cypress.config.js\` +Your configFile at /foo/bar/.projects/config-with-invalid-viewport/cypress.config.js set an invalid value: -Expected \`viewportWidth\` to be a number. Instead the value was: \`"foo"\` +Expected viewportWidth to be a number. + +Instead the value was: "foo" ` exports['e2e config throws error when invalid browser in the configuration file 1'] = ` -We found an invalid value in the file: \`cypress.config.js\` +Your configFile at /foo/bar/.projects/config-with-invalid-browser/cypress.config.js set an invalid value: + +The error occurred while validating the browsers list. + +Expected family to be either chromium or firefox. -Found an error while validating the \`browsers\` list. Expected \`family\` to be either chromium or firefox. Instead the value was: \`{"name":"bad browser","family":"unknown family","displayName":"Bad browser","version":"no version","path":"/path/to","majorVersion":123}\` +Instead the value was: + +{ + "name": "bad browser", + "family": "unknown family", + "displayName": "Bad browser", + "version": "no version", + "path": "/path/to", + "majorVersion": 123 +} ` exports['e2e config throws error when multiple default config file are found in project 1'] = ` -There is both a \`cypress.config.js\` and a \`cypress.config.ts\` at the location below: -/foo/bar/.projects/pristine-with-e2e-testing - -This sometimes happens if you do not have cypress.config.ts excluded in your tsconfig.json. +There is both a cypress.config.js and a cypress.config.ts at the location below: -Please add it to your "excludes" option, and remove from your project. + > /foo/bar/.projects/pristine-with-e2e-testing +Cypress does not know which one to read for config. Please remove one of the two and try again. ` exports['e2e config throws error when cypress.json is found in project and need migration 1'] = ` -There is a cypress.json file at the location below: -/foo/bar/.projects/pristine +There is a cypress.json file at the path: /foo/bar/.projects/pristine -Cypress 10 no longer supports 'cypress.json'. Please run \`cypress open\` to launch the migration tool to migrate to 'cypress.config.{ts|js}'. +Cypress version 10.0.0 no longer supports cypress.json. + +Please run cypress open to launch the migration tool to migrate to cypress.config.{ts|js}. ` exports['e2e config throws error when cypress.json is found in project and cypress.config.{ts|js} exists as well 1'] = ` -There is both a \`cypress.config.js\` and a cypress.json file at the location below: +There is both a cypress.config.js and a cypress.json file at the location below: + /foo/bar/.projects/multiple-config-files-with-json -Cypress no longer supports 'cypress.json' config, please remove it from your project. +Cypress no longer supports cypress.json, please remove it from your project. ` exports['e2e config throws an error if supportFile is set on the root level 1'] = ` -The \`supportFile\` configuration option was removed from the root in Cypress version \`10.0.0\`. Please update this option under each testing type property. +The supportFile configuration option is now invalid when set from the root of the config object in Cypress version 10.0.0. + +It is now configured separately as a testing type property: e2e.supportFile and component.supportFile + +{ + e2e: { + specPattern: '...', + }, + component: { + specPattern: '...', + }, +} https://on.cypress.io/migration-guide ` exports['e2e config throws an error if specPattern is set on the root level 1'] = ` -The \`specPattern\` configuration option was removed from the root in Cypress version \`10.0.0\`. Please update this option under each testing type property. +The specPattern configuration option is now invalid when set from the root of the config object in Cypress version 10.0.0. + +It is now configured separately as a testing type property: e2e.specPattern and component.specPattern + +{ + e2e: { + specPattern: '...', + }, + component: { + specPattern: '...', + }, +} https://on.cypress.io/migration-guide ` exports['e2e config throws an error if excludeSpecPattern is set on the root level 1'] = ` -The \`excludeSpecPattern\` configuration option was removed from the root in Cypress version \`10.0.0\`. Please update this option under each testing type property. +The excludeSpecPattern configuration option is now invalid when set from the root of the config object in Cypress version 10.0.0. + +It is now configured separately as a testing type property: e2e.excludeSpecPattern and component.excludeSpecPattern + +{ + e2e: { + specPattern: '...', + }, + component: { + specPattern: '...', + }, +} https://on.cypress.io/migration-guide ` exports['e2e config throws an error if baseUrl is set on the root level 1'] = ` -The \`baseUrl\` configuration option was removed from the root in Cypress version \`10.0.0\`. Please update this option under e2e testing type property. +The baseUrl configuration option is now invalid when set from the root of the config object in Cypress version 10.0.0. + +It is now configured separately as a testing type property: e2e.baseUrl + +{ + e2e: { + baseUrl: '...', + } +} https://on.cypress.io/migration-guide ` exports['e2e config throws an error if baseUrl is set on the component level 1'] = ` -The \`baseUrl\` configuration option is not valid in Component testing. Please update this option under e2e testing type property. +The component.baseUrl configuration option is not valid for component testing. + +Please remove this option or add this as an e2e testing type property: e2e.baseUrl + +{ + e2e: { + baseUrl: '...', + } +} https://on.cypress.io/migration-guide diff --git a/system-tests/__snapshots__/controllers_spec.js b/system-tests/__snapshots__/controllers_spec.js index baa33b51b8c5..185b6006d43e 100644 --- a/system-tests/__snapshots__/controllers_spec.js +++ b/system-tests/__snapshots__/controllers_spec.js @@ -18,7 +18,7 @@ exports['e2e plugins fails when spec does not exist 1'] = ` Oops...we found an error preparing this test file: - cypress/e2e/spec.js + > cypress/e2e/spec.js The error was: diff --git a/system-tests/__snapshots__/deprecated_spec.ts.js b/system-tests/__snapshots__/deprecated_spec.ts.js index 911aa1382a73..3550aa5aace0 100644 --- a/system-tests/__snapshots__/deprecated_spec.ts.js +++ b/system-tests/__snapshots__/deprecated_spec.ts.js @@ -1,3 +1,36 @@ +exports['deprecated before:browser:launch args / fails when adding unknown properties to launchOptions'] = ` + +==================================================================================================== + + (Run Starting) + + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ Cypress: 1.2.3 │ + │ Browser: FooBrowser 88 │ + │ Specs: 1 found (app.cy.js) │ + │ Searched: cypress/e2e/app.cy.js │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + + +──────────────────────────────────────────────────────────────────────────────────────────────────── + + Running: app.cy.js (1 of 1) +The launchOptions object returned by your plugin's before:browser:launch handler contained unexpected properties: + + - foo + - width + - height + +launchOptions may only contain the properties: + + - preferences + - extensions + - args + +https://on.cypress.io/browser-launch-api + +` + exports['deprecated before:browser:launch args / push and no return - warns user exactly once'] = ` ==================================================================================================== @@ -15,9 +48,9 @@ exports['deprecated before:browser:launch args / push and no return - warns user ──────────────────────────────────────────────────────────────────────────────────────────────────── Running: app.cy.js (1 of 1) -Deprecation Warning: The \`before:browser:launch\` plugin event changed its signature in version \`4.0.0\` +Deprecation Warning: The before:browser:launch plugin event changed its signature in Cypress version 4.0.0 -The \`before:browser:launch\` plugin event switched from yielding the second argument as an \`array\` of browser arguments to an options \`object\` with an \`args\` property. +The event switched from yielding the second argument as an array of browser arguments to an options object with an args property. We've detected that your code is still using the previous, deprecated interface signature. @@ -111,7 +144,7 @@ exports['deprecated before:browser:launch args / using non-deprecated API - no w ` -exports['deprecated before:browser:launch args / no mutate return'] = ` +exports['deprecated before:browser:launch args / concat return returns once per spec - [electron]'] = ` ==================================================================================================== @@ -120,14 +153,21 @@ exports['deprecated before:browser:launch args / no mutate return'] = ` ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Cypress: 1.2.3 │ │ Browser: FooBrowser 88 │ - │ Specs: 1 found (app.cy.js) │ - │ Searched: cypress/e2e/app.cy.js │ + │ Specs: 2 found (app.cy.js, app_spec2.js) │ + │ Searched: cypress/e2e/app.cy.js, cypress/e2e/app_spec2.js │ └────────────────────────────────────────────────────────────────────────────────────────────────┘ ──────────────────────────────────────────────────────────────────────────────────────────────────── - Running: app.cy.js (1 of 1) + Running: app.cy.js (1 of 2) +Deprecation Warning: The before:browser:launch plugin event changed its signature in Cypress version 4.0.0 + +The event switched from yielding the second argument as an array of browser arguments to an options object with an args property. + +We've detected that your code is still using the previous, deprecated interface signature. + +This code will not work in a future version of Cypress. Please see the upgrade guide: https://on.cypress.io/deprecated-before-browser-launch-args ✓ asserts on browser args @@ -150,95 +190,52 @@ exports['deprecated before:browser:launch args / no mutate return'] = ` └────────────────────────────────────────────────────────────────────────────────────────────────┘ -==================================================================================================== - - (Run Finished) - - - Spec Tests Passing Failing Pending Skipped - ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ - │ ✔ app.cy.js XX:XX 1 1 - - - │ - └────────────────────────────────────────────────────────────────────────────────────────────────┘ - ✔ All specs passed! XX:XX 1 1 - - - - - -` - -exports['deprecated before:browser:launch args / fails when adding unknown properties to launchOptions'] = ` - -==================================================================================================== - - (Run Starting) - - ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ - │ Cypress: 1.2.3 │ - │ Browser: FooBrowser 88 │ - │ Specs: 1 found (app.cy.js) │ - │ Searched: cypress/e2e/app.cy.js │ - └────────────────────────────────────────────────────────────────────────────────────────────────┘ - - ──────────────────────────────────────────────────────────────────────────────────────────────────── - Running: app.cy.js (1 of 1) -The \`launchOptions\` object returned by your plugin's \`before:browser:launch\` handler contained unexpected properties: + Running: app_spec2.js (2 of 2) +Deprecation Warning: The before:browser:launch plugin event changed its signature in Cypress version 4.0.0 -- foo -- width -- height +The event switched from yielding the second argument as an array of browser arguments to an options object with an args property. -\`launchOptions\` may only contain the properties: +We've detected that your code is still using the previous, deprecated interface signature. -- preferences -- extensions -- args +This code will not work in a future version of Cypress. Please see the upgrade guide: https://on.cypress.io/deprecated-before-browser-launch-args -https://on.cypress.io/browser-launch-api -` + ✓ 2 - asserts on browser args -exports['deprecated before:browser:launch args / displays errors thrown and aborts the run'] = ` + 1 passing -==================================================================================================== - (Run Starting) + (Results) ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ - │ Cypress: 1.2.3 │ - │ Browser: FooBrowser 88 │ - │ Specs: 2 found (app.cy.js, app_spec2.js) │ - │ Searched: cypress/e2e/app.cy.js, cypress/e2e/app_spec2.js │ + │ Tests: 1 │ + │ Passing: 1 │ + │ Failing: 0 │ + │ Pending: 0 │ + │ Skipped: 0 │ + │ Screenshots: 0 │ + │ Video: false │ + │ Duration: X seconds │ + │ Spec Ran: app_spec2.js │ └────────────────────────────────────────────────────────────────────────────────────────────────┘ -──────────────────────────────────────────────────────────────────────────────────────────────────── - - Running: app.cy.js (1 of 2) -Error thrown from plugins handler -Error: Error thrown from plugins handler - [stack trace lines] -` - -exports['deprecated before:browser:launch args / displays promises rejected and aborts the run'] = ` - ==================================================================================================== - (Run Starting) + (Run Finished) + + Spec Tests Passing Failing Pending Skipped ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ - │ Cypress: 1.2.3 │ - │ Browser: FooBrowser 88 │ - │ Specs: 2 found (app.cy.js, app_spec2.js) │ - │ Searched: cypress/e2e/app.cy.js, cypress/e2e/app_spec2.js │ + │ ✔ app.cy.js XX:XX 1 1 - - - │ + ├────────────────────────────────────────────────────────────────────────────────────────────────┤ + │ ✔ app_spec2.js XX:XX 1 1 - - - │ └────────────────────────────────────────────────────────────────────────────────────────────────┘ + ✔ All specs passed! XX:XX 2 2 - - - -──────────────────────────────────────────────────────────────────────────────────────────────────── - - Running: app.cy.js (1 of 2) -Promise rejected from plugins handler -Error: Promise rejected from plugins handler - [stack trace lines] ` exports['deprecated before:browser:launch args / concat return returns once per test run - [firefox,chromium]'] = ` @@ -258,9 +255,9 @@ exports['deprecated before:browser:launch args / concat return returns once per ──────────────────────────────────────────────────────────────────────────────────────────────────── Running: app.cy.js (1 of 2) -Deprecation Warning: The \`before:browser:launch\` plugin event changed its signature in version \`4.0.0\` +Deprecation Warning: The before:browser:launch plugin event changed its signature in Cypress version 4.0.0 -The \`before:browser:launch\` plugin event switched from yielding the second argument as an \`array\` of browser arguments to an options \`object\` with an \`args\` property. +The event switched from yielding the second argument as an array of browser arguments to an options object with an args property. We've detected that your code is still using the previous, deprecated interface signature. @@ -328,7 +325,7 @@ This code will not work in a future version of Cypress. Please see the upgrade g ` -exports['deprecated before:browser:launch args / concat return returns once per spec - [electron]'] = ` +exports['deprecated before:browser:launch args / no mutate return'] = ` ==================================================================================================== @@ -337,21 +334,14 @@ exports['deprecated before:browser:launch args / concat return returns once per ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Cypress: 1.2.3 │ │ Browser: FooBrowser 88 │ - │ Specs: 2 found (app.cy.js, app_spec2.js) │ - │ Searched: cypress/e2e/app.cy.js, cypress/e2e/app_spec2.js │ + │ Specs: 1 found (app.cy.js) │ + │ Searched: cypress/e2e/app.cy.js │ └────────────────────────────────────────────────────────────────────────────────────────────────┘ ──────────────────────────────────────────────────────────────────────────────────────────────────── - Running: app.cy.js (1 of 2) -Deprecation Warning: The \`before:browser:launch\` plugin event changed its signature in version \`4.0.0\` - -The \`before:browser:launch\` plugin event switched from yielding the second argument as an \`array\` of browser arguments to an options \`object\` with an \`args\` property. - -We've detected that your code is still using the previous, deprecated interface signature. - -This code will not work in a future version of Cypress. Please see the upgrade guide: https://on.cypress.io/deprecated-before-browser-launch-args + Running: app.cy.js (1 of 1) ✓ asserts on browser args @@ -374,50 +364,60 @@ This code will not work in a future version of Cypress. Please see the upgrade g └────────────────────────────────────────────────────────────────────────────────────────────────┘ -──────────────────────────────────────────────────────────────────────────────────────────────────── - - Running: app_spec2.js (2 of 2) -Deprecation Warning: The \`before:browser:launch\` plugin event changed its signature in version \`4.0.0\` +==================================================================================================== -The \`before:browser:launch\` plugin event switched from yielding the second argument as an \`array\` of browser arguments to an options \`object\` with an \`args\` property. + (Run Finished) -We've detected that your code is still using the previous, deprecated interface signature. -This code will not work in a future version of Cypress. Please see the upgrade guide: https://on.cypress.io/deprecated-before-browser-launch-args + Spec Tests Passing Failing Pending Skipped + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ ✔ app.cy.js XX:XX 1 1 - - - │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + ✔ All specs passed! XX:XX 1 1 - - - - ✓ 2 - asserts on browser args +` - 1 passing +exports['deprecated before:browser:launch args / displays errors thrown and aborts the run'] = ` +==================================================================================================== - (Results) + (Run Starting) ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ - │ Tests: 1 │ - │ Passing: 1 │ - │ Failing: 0 │ - │ Pending: 0 │ - │ Skipped: 0 │ - │ Screenshots: 0 │ - │ Video: false │ - │ Duration: X seconds │ - │ Spec Ran: app_spec2.js │ + │ Cypress: 1.2.3 │ + │ Browser: FooBrowser 88 │ + │ Specs: 2 found (app.cy.js, app_spec2.js) │ + │ Searched: cypress/e2e/app.cy.js, cypress/e2e/app_spec2.js │ └────────────────────────────────────────────────────────────────────────────────────────────────┘ -==================================================================================================== +──────────────────────────────────────────────────────────────────────────────────────────────────── + + Running: app.cy.js (1 of 2) +Error thrown from plugins handler +Error: Error thrown from plugins handler + [stack trace lines] +` - (Run Finished) +exports['deprecated before:browser:launch args / displays promises rejected and aborts the run'] = ` +==================================================================================================== + + (Run Starting) - Spec Tests Passing Failing Pending Skipped ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ - │ ✔ app.cy.js XX:XX 1 1 - - - │ - ├────────────────────────────────────────────────────────────────────────────────────────────────┤ - │ ✔ app_spec2.js XX:XX 1 1 - - - │ + │ Cypress: 1.2.3 │ + │ Browser: FooBrowser 88 │ + │ Specs: 2 found (app.cy.js, app_spec2.js) │ + │ Searched: cypress/e2e/app.cy.js, cypress/e2e/app_spec2.js │ └────────────────────────────────────────────────────────────────────────────────────────────────┘ - ✔ All specs passed! XX:XX 2 2 - - - +──────────────────────────────────────────────────────────────────────────────────────────────────── + + Running: app.cy.js (1 of 2) +Promise rejected from plugins handler +Error: Promise rejected from plugins handler + [stack trace lines] ` diff --git a/system-tests/__snapshots__/es_modules_spec.js b/system-tests/__snapshots__/es_modules_spec.js index 3ceca7468e86..6a65b2016426 100644 --- a/system-tests/__snapshots__/es_modules_spec.js +++ b/system-tests/__snapshots__/es_modules_spec.js @@ -82,7 +82,7 @@ exports['e2e es modules fails 1'] = ` Oops...we found an error preparing this test file: - cypress/e2e/es_module_import_failing.cy.js + > cypress/e2e/es_module_import_failing.cy.js The error was: diff --git a/system-tests/__snapshots__/multiple_support_files_spec.js b/system-tests/__snapshots__/multiple_support_files_spec.js index 208a563ab506..acf6c8d84b45 100644 --- a/system-tests/__snapshots__/multiple_support_files_spec.js +++ b/system-tests/__snapshots__/multiple_support_files_spec.js @@ -1,8 +1,13 @@ exports['e2e multiple support files passes 1'] = ` -There are multiple support files. +There were multiple support files found matching your supportFile pattern. -Your \`supportFile\` is set to \`/foo/bar/.projects/multiple-support-files/cypress/support/e2e.{js,jsx,ts,tsx}\`, and we found \`/foo/bar/.projects/multiple-support-files/cypress/support/e2e.js, /foo/bar/.projects/multiple-support-files/cypress/support/e2e.ts\`. +Your supportFile is set to: /foo/bar/.projects/multiple-support-files/cypress/support/e2e.{js,jsx,ts,tsx} -Correct your supportFile config or merge the files into one. +We found the following files: + + - /foo/bar/.projects/multiple-support-files/cypress/support/e2e.js + - /foo/bar/.projects/multiple-support-files/cypress/support/e2e.ts + +Please remove or combine the support files into a single file. ` diff --git a/system-tests/__snapshots__/network_error_handling_spec.js b/system-tests/__snapshots__/network_error_handling_spec.js index f051ee6cfcec..1db110efbef8 100644 --- a/system-tests/__snapshots__/network_error_handling_spec.js +++ b/system-tests/__snapshots__/network_error_handling_spec.js @@ -3,7 +3,7 @@ Cypress could not verify that this server is running: > http://never-gonna-exist.invalid -We are verifying this server because it has been configured as your \`baseUrl\`. +We are verifying this server because it has been configured as your baseUrl. Cypress automatically waits until your server is accessible before running tests. diff --git a/system-tests/__snapshots__/non_root_read_only_fs_spec.ts.js b/system-tests/__snapshots__/non_root_read_only_fs_spec.ts.js index ff3dadf356b5..53ede24f6005 100644 --- a/system-tests/__snapshots__/non_root_read_only_fs_spec.ts.js +++ b/system-tests/__snapshots__/non_root_read_only_fs_spec.ts.js @@ -1,7 +1,7 @@ exports['e2e readonly fs / warns when unable to write to disk'] = ` ✅ not running as root ✅ /foo/bar/.projects/read-only-project-root is not writable -Folder /foo/bar/.projects/read-only-project-root is not writable. +This folder is not writable: /foo/bar/.projects/read-only-project-root Writing to this directory is required by Cypress in order to store screenshots and videos. diff --git a/system-tests/__snapshots__/plugin_run_events_spec.ts.js b/system-tests/__snapshots__/plugin_run_events_spec.ts.js index 0d00cbccba55..70b1007d6943 100644 --- a/system-tests/__snapshots__/plugin_run_events_spec.ts.js +++ b/system-tests/__snapshots__/plugin_run_events_spec.ts.js @@ -160,12 +160,10 @@ exports['e2e plugin run events / fails run if event handler throws'] = ` ──────────────────────────────────────────────────────────────────────────────────────────────────── Running: run_event_throws.cy.js (1 of 1) -An error was thrown in your plugins file while executing the handler for the 'before:spec' event. +An error was thrown in your plugins file while executing the handler for the before:spec event. The error we received was: Error: error thrown in before:spec [stack trace lines] - - ` diff --git a/system-tests/__snapshots__/plugins_spec.js b/system-tests/__snapshots__/plugins_spec.js index f7a61b3e0620..069de77d9462 100644 --- a/system-tests/__snapshots__/plugins_spec.js +++ b/system-tests/__snapshots__/plugins_spec.js @@ -119,35 +119,45 @@ exports['e2e plugins can modify config from plugins 1'] = ` ` exports['e2e plugins catches invalid browsers list returned from plugins 1'] = ` -An invalid configuration value returned from the setupNodeEvents on config file: \`cypress.config.js\` +Your configFile as cypress.config.js set an invalid value: Expected at least one browser ` exports['e2e plugins catches invalid browser returned from plugins 1'] = ` -An invalid configuration value returned from the setupNodeEvents on config file: \`cypress.config.js\` +Your configFile at cypress.config.js set an invalid value: -Found an error while validating the \`browsers\` list. Expected \`displayName\` to be a non-empty string. Instead the value was: \`{"name":"browser name","family":"chromium"}\` +The error occurred while validating the browsers list. + +Expected displayName to be a non-empty string. + +Instead the value was: + +{ + "name": "browser name", + "family": "chromium" +} ` exports['e2e plugins can filter browsers from config 1'] = ` -The specified browser was not found on your system or is not supported by Cypress: \`chrome\` +Can't run because you've entered an invalid browser name. + +Browser: chrome was not found on your system or is not supported by Cypress. Cypress supports the following browsers: -- chrome -- chromium -- edge -- electron -- firefox + - electron + - chrome + - chromium + - chrome:canary + - edge + - firefox You can also use a custom browser: https://on.cypress.io/customize-browsers Available browsers found on your system are: -- electron - -Read more about how to troubleshoot launching browsers: https://on.cypress.io/troubleshooting-launching-browsers + - electron ` @@ -346,9 +356,11 @@ exports['e2e plugins calls after:screenshot for cy.screenshot() and failure scre ` exports['e2e plugins catches invalid viewportWidth returned from plugins 1'] = ` -An invalid configuration value returned from the setupNodeEvents on config file: \`cypress.config.js\` +Your configFile at cypress.config.js set an invalid value: + +Expected viewportWidth to be a number. -Expected \`viewportWidth\` to be a number. Instead the value was: \`"foo"\` +Instead the value was: "foo" ` @@ -370,10 +382,11 @@ exports['e2e plugins fails when there is an async error inside an event handler Running: app.cy.js (1 of 1) +Your configFile threw an error from: cypress.config.js -The following error was thrown by a plugin. We stopped running your tests because a plugin crashed. Please check your e2e.setupNodeEvents method in \`cypress.config.js\` +We stopped running your tests because your config file crashed. - Error: Async error from plugins file +Error: Async error from plugins file [stack trace lines] (Results) @@ -405,43 +418,26 @@ The following error was thrown by a plugin. We stopped running your tests becaus ` -exports['e2e plugins fails when setupNodeEvents is not a function 1'] = ` -The \`setupNodeEvents\` method must BE a function with the following signature: - -\`\`\` -setupNodeEvents (on, config) { - // configure plugins here -} -\`\`\` - -Learn more: https://on.cypress.io/plugins-api - -We loaded the \`setupNodeEvents\` from: \`/foo/bar/.projects/plugin-empty/cypress.config.js\` - -It exported: - - "foo" - -` - exports['e2e plugins fails when invalid event is registered 1'] = ` -The following validation error was thrown by your plugins file (\`/foo/bar/.projects/plugin-validation-error/cypress.config.js\`). +Your configFile threw a validation error from: /foo/bar/.projects/plugin-validation-error/cypress.config.js - Error: You must pass a valid event name when registering a plugin. +You must pass a valid event name when registering a plugin. -You passed: \`invalid:event\` +You passed: invalid:event The following are valid events: -- after:run -- after:screenshot -- after:spec -- before:browser:launch -- before:run -- before:spec -- dev-server:start -- file:preprocessor -- task + - after:run + - after:screenshot + - after:spec + - before:browser:launch + - before:run + - before:spec + - dev-server:start + - file:preprocessor + - task + +InvalidEventNameError: invalid event name registered: invalid:event [stack trace lines] ` @@ -510,4 +506,78 @@ exports['e2e plugins does not report more screenshots than exist if user overwri ✔ All specs passed! XX:XX 3 3 - - - +` + +exports['e2e plugins fails when require throws synchronously 1'] = ` +Your configFile is invalid: /foo/bar/.projects/plugins-root-sync-error/cypress.config.js + +It threw an error when required, check the stack trace below: + +RootSyncError: Root sync error from plugins file + [stack trace lines] +` + +exports['e2e plugins fails when function throws synchronously 1'] = ` +Your configFile threw an error from: /foo/bar/.projects/plugins-function-sync-error/cypress.config.js + +The error was thrown while executing your e2e.setupNodeEvents() function: + +FunctionSyncError: Function sync error from plugins file + [stack trace lines] +` + +exports['e2e plugins fails when invalid event handler is registered 1'] = ` +Your configFile threw an error from: /foo/bar/.projects/plugin-invalid-event-handler-error/cypress.config.js + +The error was thrown while executing your e2e.setupNodeEvents() function: + +InvalidEventHandlerError: The handler for the event \`task\` must be an object + [stack trace lines] +` + +exports['e2e plugins fails when setupNodeEvents is not a function 1'] = ` +Your configFile is invalid: /foo/bar/.projects/plugin-empty/cypress.config.js + +The e2e.setupNodeEvents() function must be defined with the following signature: + +{ + e2e: { + setupNodeEvents(on, config) { + // configure tasks and plugins here + } + } +} + +Instead we saw: + +"foo" + +https://on.cypress.io/plugins-api + + +` + +exports['e2e plugins fails when there is no function exported 1'] = ` +Your configFile is invalid: /foo/bar/.projects/plugin-no-function-return/cypress.config.js + +The e2e.setupNodeEvents() function must be defined with the following signature: + +{ + e2e: { + setupNodeEvents(on, config) { + // configure tasks and plugins here + } + } +} + +Instead we saw: + +{ + "foo": "foo", + "bar": "bar" +} + +https://on.cypress.io/plugins-api + + ` diff --git a/system-tests/__snapshots__/record_spec.js b/system-tests/__snapshots__/record_spec.js index 4e27cbe33aa3..9158e59d0708 100644 --- a/system-tests/__snapshots__/record_spec.js +++ b/system-tests/__snapshots__/record_spec.js @@ -22,7 +22,7 @@ exports['e2e record passing passes 1'] = ` Oops...we found an error preparing this test file: - cypress/e2e/record_error.cy.js + > cypress/e2e/record_error.cy.js The error was: @@ -257,9 +257,9 @@ We dynamically generated a new test to display this failure. ` exports['e2e record api interaction errors project 404 errors and exits 1'] = ` -We could not find a project with the ID: pid123 +We could not find a Dashboard project with the projectId: pid123 -This projectId came from your 'cypress-with-project-id.config.js' file or an environment variable. +This projectId came from your cypress-with-project-id.config.js file or an environment variable. Please log into the Dashboard and find your project. @@ -358,9 +358,9 @@ You passed the --record flag but did not provide us your Record Key. You can pass us your Record Key like this: - cypress run --record --key + $ cypress run --record --key -You can also set the key as an environment variable with the name CYPRESS_RECORD_KEY. +You can also set the key as an environment variable with the name: CYPRESS_RECORD_KEY https://on.cypress.io/how-do-i-record-runs @@ -369,11 +369,11 @@ https://on.cypress.io/how-do-i-record-runs exports['e2e record projectId errors and exits without projectId 1'] = ` You passed the --record flag but this project has not been setup to record. -This project is missing the 'projectId' inside of 'cypress.config.js'. +This project is missing the projectId inside of: cypress.config.js We cannot uniquely identify this project without this id. -You need to setup this project to record. This will generate a unique 'projectId'. +You need to setup this project to record. This will generate a unique projectId. Alternatively if you omit the --record flag this project will run without recording. @@ -382,7 +382,7 @@ https://on.cypress.io/recording-project-runs ` exports['e2e record api interaction errors recordKey and projectId errors and exits on 401 1'] = ` -Your Record Key f858a...ee7e1 is not valid with this project: pid123 +Your Record Key f858a...ee7e1 is not valid with this projectId: pid123 It may have been recently revoked by you or another user. @@ -552,20 +552,16 @@ exports['e2e record api interaction errors uploading assets warns but proceeds 1 exports['e2e record misconfiguration errors and exits when no specs found 1'] = ` Can't run because no spec files were found. -We searched for any files matching this glob pattern: +We searched for specs matching this glob pattern: -cypress/e2e/notfound/** - -Relative to the project root folder: - -/foo/bar/.projects/e2e + > /foo/bar/.projects/e2e/cypress/e2e/notfound/** ` exports['e2e record recordKey warns but does not exit when is forked pr 1'] = ` Warning: It looks like you are trying to record this run from a forked PR. -The 'Record Key' is missing. Your CI provider is likely not passing private environment variables to builds from forks. +The Record Key is missing. Your CI provider is likely not passing private environment variables to builds from forks. These results will not be recorded. @@ -731,7 +727,7 @@ exports['e2e record parallelization passes in parallel with group 2'] = ` Oops...we found an error preparing this test file: - cypress/e2e/record_error.cy.js + > cypress/e2e/record_error.cy.js The error was: @@ -1171,7 +1167,7 @@ StatusCodeError: 500 - "Internal Server Error" exports['e2e record recordKey warns but does not exit when is forked pr and parallel 1'] = ` Warning: It looks like you are trying to record this run from a forked PR. -The 'Record Key' is missing. Your CI provider is likely not passing private environment variables to builds from forks. +The Record Key is missing. Your CI provider is likely not passing private environment variables to builds from forks. These results will not be recorded. @@ -1454,6 +1450,7 @@ exports['e2e record api interaction warnings create run warnings unknown warning Warning from Cypress Dashboard: You are almost out of time Details: + { "code": "OUT_OF_TIME", "name": "OutOfTime", @@ -2639,14 +2636,17 @@ exports['e2e record empty specs succeeds when empty spec file 1'] = ` ` exports['e2e record misconfiguration errors and exits when no browser found 1'] = ` -The specified browser was not found on your system or is not supported by Cypress: \`browserDoesNotExist\` +Can't run because you've entered an invalid browser name. + +Browser: browserDoesNotExist was not found on your system or is not supported by Cypress. Cypress supports the following browsers: -- chrome -- chromium -- edge -- electron -- firefox + - electron + - chrome + - chromium + - chrome:canary + - edge + - firefox You can also use a custom browser: https://on.cypress.io/customize-browsers @@ -2741,3 +2741,42 @@ exports['e2e record quiet mode respects quiet mode 1'] = ` ` + +exports['e2e record api interaction errors create run 412 errors and exits when request schema is invalid 1'] = ` +Recording this run failed because the request was invalid. + +request should follow postRunRequest@2.0.0 schema + +Errors: + +[ + "data has additional properties: group, parallel, ciBuildId, tags, testingType, runnerCapabilities", + "data.platform is the wrong type" +] + +Request Sent: + +{ + "ci": null, + "specs": [ + "cypress/e2e/record_pass.cy.js" + ], + "commit": null, + "group": null, + "platform": null, + "parallel": null, + "ciBuildId": null, + "projectId": "pid123", + "recordKey": "f858a2bc-b469-4e48-be67-0876339ee7e1", + "specPattern": "cypress/e2e/record_pass*", + "tags": [ + "" + ], + "testingType": "e2e", + "runnerCapabilities": { + "dynamicSpecsInSerialMode": true, + "skipSpecAction": true + } +} + +` diff --git a/system-tests/__snapshots__/reporters_spec.js b/system-tests/__snapshots__/reporters_spec.js index 5206cf658a6b..f2a240c238c6 100644 --- a/system-tests/__snapshots__/reporters_spec.js +++ b/system-tests/__snapshots__/reporters_spec.js @@ -1,14 +1,14 @@ exports['e2e reporters reports error if cannot load reporter 1'] = ` -Could not load reporter by name: module-does-not-exist +Error loading the reporter: module-does-not-exist We searched for the reporter in these paths: -- /foo/bar/.projects/e2e/module-does-not-exist -- /foo/bar/.projects/e2e/node_modules/module-does-not-exist + - /foo/bar/.projects/e2e/module-does-not-exist + - /foo/bar/.projects/e2e/node_modules/module-does-not-exist -The error we received was: +Learn more at https://on.cypress.io/reporters -Cannot find module '/foo/bar/.projects/e2e/node_modules/module-does-not-exist' +Error: Cannot find module '/foo/bar/.projects/e2e/node_modules/module-does-not-exist' Require stack: - lib/reporter.js - lib/project-base.ts @@ -16,8 +16,8 @@ Require stack: - lib/cypress.js - index.js - + [stack trace lines] -Learn more at https://on.cypress.io/reporters ` @@ -662,19 +662,18 @@ Because this error occurred during a \`after all\` hook we are skipping the rema ` exports['e2e reporters reports error when thrown from reporter 1'] = ` -Could not load reporter by name: reporters/throws.js +Error loading the reporter: reporters/throws.js We searched for the reporter in these paths: -- /foo/bar/.projects/e2e/reporters/throws.js -- /foo/bar/.projects/e2e/node_modules/reporters/throws.js + - /foo/bar/.projects/e2e/reporters/throws.js + - /foo/bar/.projects/e2e/node_modules/reporters/throws.js -The error we received was: +Learn more at https://on.cypress.io/reporters Error: this reporter threw an error [stack trace lines] -Learn more at https://on.cypress.io/reporters ` diff --git a/system-tests/__snapshots__/retries_spec.ts.js b/system-tests/__snapshots__/retries_spec.ts.js index bc674637be17..44581c1bd674 100644 --- a/system-tests/__snapshots__/retries_spec.ts.js +++ b/system-tests/__snapshots__/retries_spec.ts.js @@ -67,9 +67,9 @@ exports['retries / supports retries'] = ` ` exports['retries / warns about retries plugin'] = ` -We've detected that the incompatible plugin \`cypress-plugin-retries\` is installed at \`node_modules/cypress-plugin-retries\`. +We've detected that the incompatible plugin cypress-plugin-retries is installed at: node_modules/cypress-plugin-retries -Test retries is now supported in Cypress version \`5.0.0\`. +Test retries is now natively supported in Cypress version 5.0.0. Remove the plugin from your dependencies to silence this warning. diff --git a/system-tests/__snapshots__/specs_spec.js b/system-tests/__snapshots__/specs_spec.js index 3ddfdf5bb9c9..901fff791597 100644 --- a/system-tests/__snapshots__/specs_spec.js +++ b/system-tests/__snapshots__/specs_spec.js @@ -1,12 +1,35 @@ -exports['e2e specs failing when no specs found 1'] = ` +exports['e2e specs failing when no specs found and default specPattern 1'] = ` Can't run because no spec files were found. -We searched for any files matching this glob pattern: +We searched for specs matching this glob pattern: -**/*.no-specs-found-with-this-pattern + > /foo/bar/.projects/no-specs/cypress/e2e/**/*.cy.{js,jsx,ts,tsx} -Relative to the project root folder: +` + +exports['e2e specs failing when no specs found and custom specPattern 1'] = ` +Can't run because no spec files were found. + +We searched for specs matching this glob pattern: + + > /foo/bar/.projects/no-specs-custom-pattern/src/**/*.cy.{js,jsx} + +` + +exports['e2e specs failing when no specs found and spec pattern provided from CLI 1'] = ` +Can't run because no spec files were found. + +We searched for specs matching this glob pattern: + + > /foo/bar/.projects/no-specs/cypress/e2e/does/not/exist/**notfound** + +` + +exports['e2e specs failing when no specs found with custom spec pattern and spec pattern provided from CLI 1'] = ` +Can't run because no spec files were found. + +We searched for specs matching this glob pattern: -/foo/bar/.projects/no-specs-found + > /foo/bar/.projects/no-specs-custom-pattern/cypress/e2e/does/not/exist/**notfound** ` diff --git a/system-tests/__snapshots__/stdout_spec.js b/system-tests/__snapshots__/stdout_spec.js index 2344c29a8aeb..5de39273771f 100644 --- a/system-tests/__snapshots__/stdout_spec.js +++ b/system-tests/__snapshots__/stdout_spec.js @@ -137,7 +137,7 @@ exports['e2e stdout displays errors from exiting early due to bundle errors 1'] Oops...we found an error preparing this test file: - cypress/e2e/stdout_exit_early_failing.cy.js + > cypress/e2e/stdout_exit_early_failing.cy.js The error was: diff --git a/system-tests/__snapshots__/system_node_spec.js b/system-tests/__snapshots__/system_node_spec.js index f1b394ecd441..2c9410d754d4 100644 --- a/system-tests/__snapshots__/system_node_spec.js +++ b/system-tests/__snapshots__/system_node_spec.js @@ -1,6 +1,9 @@ exports['e2e system node uses system node when launching plugins file 1'] = ` -Deprecation Warning: \`nodeVersion\` is currently set to \`system\` in the \`cypress.config.js\` configuration file. As of Cypress version \`9.0.0\` the default behavior of \`nodeVersion\` has changed to always use the version of Node used to start cypress via the cli. -Please remove the \`nodeVersion\` configuration option from \`cypress.config.js\`. +Deprecation Warning: nodeVersion is currently set to system in the cypress.config.js configuration file. + +As of Cypress version 9.0.0 the default behavior of nodeVersion has changed to always use the version of Node used to start cypress via the cli. + +Please remove the nodeVersion configuration option from cypress.config.js. ==================================================================================================== @@ -59,6 +62,73 @@ Please remove the \`nodeVersion\` configuration option from \`cypress.config.js\ ✔ All specs passed! XX:XX 1 1 - - - +` + +exports['e2e system node uses bundled node when launching plugins file 1'] = ` +Deprecation Warning: nodeVersion is currently set to bundled in the cypress.config.js configuration file. + +As of Cypress version 9.0.0 the default behavior of nodeVersion has changed to always use the version of Node used to start cypress via the cli. + +When nodeVersion is set to bundled, Cypress will use the version of Node bundled with electron. This can cause problems running certain plugins or integrations. + +As the nodeVersion configuration option will be removed in a future release, it is recommended to remove the nodeVersion configuration option from cypress.config.js. + + +==================================================================================================== + + (Run Starting) + + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ Cypress: 1.2.3 │ + │ Browser: FooBrowser 88 │ + │ Specs: 1 found (bundled.spec.js) │ + │ Searched: cypress/integration/bundled.spec.js │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + + +──────────────────────────────────────────────────────────────────────────────────────────────────── + + Running: bundled.spec.js (1 of 1) + + + ✓ has expected resolvedNodePath and resolvedNodeVersion + + 1 passing + + + (Results) + + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ Tests: 1 │ + │ Passing: 1 │ + │ Failing: 0 │ + │ Pending: 0 │ + │ Skipped: 0 │ + │ Screenshots: 0 │ + │ Video: true │ + │ Duration: X seconds │ + │ Spec Ran: bundled.spec.js │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + + + (Video) + + - Started processing: Compressing to 32 CRF + - Finished processing: /XXX/XXX/XXX/cypress/videos/bundled.spec.js.mp4 (X second) + + +==================================================================================================== + + (Run Finished) + + + Spec Tests Passing Failing Pending Skipped + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ ✔ bundled.spec.js XX:XX 1 1 - - - │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + ✔ All specs passed! XX:XX 1 1 - - - + + ` exports['e2e system node uses default node when launching plugins file 1'] = ` diff --git a/system-tests/__snapshots__/task_spec.js b/system-tests/__snapshots__/task_spec.js index 121c65e7e3f1..ec5c96b6c0f7 100644 --- a/system-tests/__snapshots__/task_spec.js +++ b/system-tests/__snapshots__/task_spec.js @@ -1,5 +1,9 @@ exports['e2e task merges task events on subsequent registrations and logs warning for conflicts 1'] = ` -Warning: Multiple attempts to register the following task(s): two. Only the last attempt will be registered. +Warning: Multiple attempts to register the following task(s): + + - two + +Only the last attempt will be registered. ==================================================================================================== diff --git a/system-tests/__snapshots__/testConfigOverrides_spec.ts.js b/system-tests/__snapshots__/testConfigOverrides_spec.ts.js index 0468db7521fa..6380262726ca 100644 --- a/system-tests/__snapshots__/testConfigOverrides_spec.ts.js +++ b/system-tests/__snapshots__/testConfigOverrides_spec.ts.js @@ -180,18 +180,24 @@ exports['testConfigOverrides / fails when passing invalid config values - [chrom 8 failing 1) inline test config override throws error: - Error: Expected \`baseUrl\` to be a fully qualified URL (starting with \`http://\` or \`https://\`). Instead the value was: \`""\` + Error: Expected \`baseUrl\` to be a fully qualified URL (starting with \`http://\` or \`https://\`). + +Instead the value was: \`""\`\` [stack trace lines] 2) inline test config override throws error when executed within cy cmd: - Error: Expected \`baseUrl\` to be a fully qualified URL (starting with \`http://\` or \`https://\`). Instead the value was: \`"null"\` + Error: Expected \`baseUrl\` to be a fully qualified URL (starting with \`http://\` or \`https://\`). + +Instead the value was: \`"null"\`\` [stack trace lines] 3) context config overrides throws error runs: CypressError: The config override passed to your test has the following validation error: -Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls. Instead the value was: \`"1"\` +Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls. + +Instead the value was: \`"1"\`\` https://on.cypress.io/config Error @@ -201,7 +207,9 @@ https://on.cypress.io/config 1st test fails on overrides: CypressError: The config override passed to your test has the following validation error: -Expected \`defaultCommandTimeout\` to be a number. Instead the value was: \`"500"\` +Expected \`defaultCommandTimeout\` to be a number. + +Instead the value was: \`"500"\`\` https://on.cypress.io/config Error @@ -211,7 +219,9 @@ https://on.cypress.io/config 2nd test fails on overrides: CypressError: The config override passed to your test has the following validation error: -Expected \`defaultCommandTimeout\` to be a number. Instead the value was: \`"500"\` +Expected \`defaultCommandTimeout\` to be a number. + +Instead the value was: \`"500"\`\` https://on.cypress.io/config Error @@ -222,7 +232,9 @@ https://on.cypress.io/config throws error at the correct line number: CypressError: The config override passed to your test has the following validation error: -Expected \`baseUrl\` to be a fully qualified URL (starting with \`http://\` or \`https://\`). Instead the value was: \`"not_an_http_url"\` +Expected \`baseUrl\` to be a fully qualified URL (starting with \`http://\` or \`https://\`). + +Instead the value was: \`"not_an_http_url"\`\` https://on.cypress.io/config Error @@ -232,7 +244,9 @@ https://on.cypress.io/config "before all" hook for "test config override throws error": CypressError: The config override passed to your test has the following validation error: -Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls. Instead the value was: \`"1"\` +Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls. + +Instead the value was: \`"1"\`\` https://on.cypress.io/config @@ -244,7 +258,9 @@ Because this error occurred during a \`before all\` hook we are skipping the rem test config override throws error: CypressError: The config override passed to your test has the following validation error: -Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls. Instead the value was: \`"1"\` +Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls. + +Instead the value was: \`"1"\`\` https://on.cypress.io/config Error @@ -332,12 +348,16 @@ exports['testConfigOverrides / fails when passing invalid config values with bef 1) runs all tests inline test config override throws error: - Error: Expected \`baseUrl\` to be a fully qualified URL (starting with \`http://\` or \`https://\`). Instead the value was: \`""\` + Error: Expected \`baseUrl\` to be a fully qualified URL (starting with \`http://\` or \`https://\`). + +Instead the value was: \`""\`\` [stack trace lines] 2) runs all tests inline test config override throws error when executed within cy cmd: - Error: Expected \`baseUrl\` to be a fully qualified URL (starting with \`http://\` or \`https://\`). Instead the value was: \`"null"\` + Error: Expected \`baseUrl\` to be a fully qualified URL (starting with \`http://\` or \`https://\`). + +Instead the value was: \`"null"\`\` [stack trace lines] 3) runs all tests @@ -345,7 +365,9 @@ exports['testConfigOverrides / fails when passing invalid config values with bef runs: CypressError: The config override passed to your test has the following validation error: -Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls. Instead the value was: \`"1"\` +Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls. + +Instead the value was: \`"1"\`\` https://on.cypress.io/config Error @@ -356,7 +378,9 @@ https://on.cypress.io/config 1st test fails on overrides: CypressError: The config override passed to your test has the following validation error: -Expected \`defaultCommandTimeout\` to be a number. Instead the value was: \`"500"\` +Expected \`defaultCommandTimeout\` to be a number. + +Instead the value was: \`"500"\`\` https://on.cypress.io/config Error @@ -367,7 +391,9 @@ https://on.cypress.io/config 2nd test fails on overrides: CypressError: The config override passed to your test has the following validation error: -Expected \`defaultCommandTimeout\` to be a number. Instead the value was: \`"500"\` +Expected \`defaultCommandTimeout\` to be a number. + +Instead the value was: \`"500"\`\` https://on.cypress.io/config Error @@ -379,7 +405,9 @@ https://on.cypress.io/config throws error at the correct line number: CypressError: The config override passed to your test has the following validation error: -Expected \`baseUrl\` to be a fully qualified URL (starting with \`http://\` or \`https://\`). Instead the value was: \`"not_an_http_url"\` +Expected \`baseUrl\` to be a fully qualified URL (starting with \`http://\` or \`https://\`). + +Instead the value was: \`"not_an_http_url"\`\` https://on.cypress.io/config Error @@ -390,7 +418,9 @@ https://on.cypress.io/config "before all" hook for "test config override throws error": CypressError: The config override passed to your test has the following validation error: -Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls. Instead the value was: \`"1"\` +Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls. + +Instead the value was: \`"1"\`\` https://on.cypress.io/config @@ -403,7 +433,9 @@ Because this error occurred during a \`before all\` hook we are skipping the rem test config override throws error: CypressError: The config override passed to your test has the following validation error: -Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls. Instead the value was: \`"1"\` +Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls. + +Instead the value was: \`"1"\`\` https://on.cypress.io/config Error @@ -483,7 +515,9 @@ exports['testConfigOverrides / correctly fails when invalid config values for it throws error at the correct line number: CypressError: The config override passed to your test has the following validation error: -Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls. Instead the value was: \`"1"\` +Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls. + +Instead the value was: \`"1"\`\` https://on.cypress.io/config Error @@ -565,18 +599,24 @@ exports['testConfigOverrides / fails when passing invalid config values - [firef 8 failing 1) inline test config override throws error: - Error: Expected \`baseUrl\` to be a fully qualified URL (starting with \`http://\` or \`https://\`). Instead the value was: \`""\` + Error: Expected \`baseUrl\` to be a fully qualified URL (starting with \`http://\` or \`https://\`). + +Instead the value was: \`""\`\` [stack trace lines] 2) inline test config override throws error when executed within cy cmd: - Error: Expected \`baseUrl\` to be a fully qualified URL (starting with \`http://\` or \`https://\`). Instead the value was: \`"null"\` + Error: Expected \`baseUrl\` to be a fully qualified URL (starting with \`http://\` or \`https://\`). + +Instead the value was: \`"null"\`\` [stack trace lines] 3) context config overrides throws error runs: CypressError: The config override passed to your test has the following validation error: -Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls. Instead the value was: \`"1"\` +Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls. + +Instead the value was: \`"1"\`\` https://on.cypress.io/config [stack trace lines] @@ -585,7 +625,9 @@ https://on.cypress.io/config 1st test fails on overrides: CypressError: The config override passed to your test has the following validation error: -Expected \`defaultCommandTimeout\` to be a number. Instead the value was: \`"500"\` +Expected \`defaultCommandTimeout\` to be a number. + +Instead the value was: \`"500"\`\` https://on.cypress.io/config [stack trace lines] @@ -594,7 +636,9 @@ https://on.cypress.io/config 2nd test fails on overrides: CypressError: The config override passed to your test has the following validation error: -Expected \`defaultCommandTimeout\` to be a number. Instead the value was: \`"500"\` +Expected \`defaultCommandTimeout\` to be a number. + +Instead the value was: \`"500"\`\` https://on.cypress.io/config [stack trace lines] @@ -604,7 +648,9 @@ https://on.cypress.io/config throws error at the correct line number: CypressError: The config override passed to your test has the following validation error: -Expected \`baseUrl\` to be a fully qualified URL (starting with \`http://\` or \`https://\`). Instead the value was: \`"not_an_http_url"\` +Expected \`baseUrl\` to be a fully qualified URL (starting with \`http://\` or \`https://\`). + +Instead the value was: \`"not_an_http_url"\`\` https://on.cypress.io/config [stack trace lines] @@ -613,7 +659,9 @@ https://on.cypress.io/config "before all" hook for "test config override throws error": CypressError: The config override passed to your test has the following validation error: -Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls. Instead the value was: \`"1"\` +Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls. + +Instead the value was: \`"1"\`\` https://on.cypress.io/config @@ -624,7 +672,9 @@ Because this error occurred during a \`before all\` hook we are skipping the rem test config override throws error: CypressError: The config override passed to your test has the following validation error: -Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls. Instead the value was: \`"1"\` +Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls. + +Instead the value was: \`"1"\`\` https://on.cypress.io/config [stack trace lines] @@ -711,12 +761,16 @@ exports['testConfigOverrides / fails when passing invalid config values with bef 1) runs all tests inline test config override throws error: - Error: Expected \`baseUrl\` to be a fully qualified URL (starting with \`http://\` or \`https://\`). Instead the value was: \`""\` + Error: Expected \`baseUrl\` to be a fully qualified URL (starting with \`http://\` or \`https://\`). + +Instead the value was: \`""\`\` [stack trace lines] 2) runs all tests inline test config override throws error when executed within cy cmd: - Error: Expected \`baseUrl\` to be a fully qualified URL (starting with \`http://\` or \`https://\`). Instead the value was: \`"null"\` + Error: Expected \`baseUrl\` to be a fully qualified URL (starting with \`http://\` or \`https://\`). + +Instead the value was: \`"null"\`\` [stack trace lines] 3) runs all tests @@ -724,7 +778,9 @@ exports['testConfigOverrides / fails when passing invalid config values with bef runs: CypressError: The config override passed to your test has the following validation error: -Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls. Instead the value was: \`"1"\` +Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls. + +Instead the value was: \`"1"\`\` https://on.cypress.io/config [stack trace lines] @@ -734,7 +790,9 @@ https://on.cypress.io/config 1st test fails on overrides: CypressError: The config override passed to your test has the following validation error: -Expected \`defaultCommandTimeout\` to be a number. Instead the value was: \`"500"\` +Expected \`defaultCommandTimeout\` to be a number. + +Instead the value was: \`"500"\`\` https://on.cypress.io/config [stack trace lines] @@ -744,7 +802,9 @@ https://on.cypress.io/config 2nd test fails on overrides: CypressError: The config override passed to your test has the following validation error: -Expected \`defaultCommandTimeout\` to be a number. Instead the value was: \`"500"\` +Expected \`defaultCommandTimeout\` to be a number. + +Instead the value was: \`"500"\`\` https://on.cypress.io/config [stack trace lines] @@ -755,7 +815,9 @@ https://on.cypress.io/config throws error at the correct line number: CypressError: The config override passed to your test has the following validation error: -Expected \`baseUrl\` to be a fully qualified URL (starting with \`http://\` or \`https://\`). Instead the value was: \`"not_an_http_url"\` +Expected \`baseUrl\` to be a fully qualified URL (starting with \`http://\` or \`https://\`). + +Instead the value was: \`"not_an_http_url"\`\` https://on.cypress.io/config [stack trace lines] @@ -765,7 +827,9 @@ https://on.cypress.io/config "before all" hook for "test config override throws error": CypressError: The config override passed to your test has the following validation error: -Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls. Instead the value was: \`"1"\` +Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls. + +Instead the value was: \`"1"\`\` https://on.cypress.io/config @@ -777,7 +841,9 @@ Because this error occurred during a \`before all\` hook we are skipping the rem test config override throws error: CypressError: The config override passed to your test has the following validation error: -Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls. Instead the value was: \`"1"\` +Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls. + +Instead the value was: \`"1"\`\` https://on.cypress.io/config [stack trace lines] @@ -856,7 +922,9 @@ exports['testConfigOverrides / correctly fails when invalid config values for it throws error at the correct line number: CypressError: The config override passed to your test has the following validation error: -Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls. Instead the value was: \`"1"\` +Expected \`retries\` to be a positive number or null or an object with keys "openMode" and "runMode" with values of numbers or nulls. + +Instead the value was: \`"1"\`\` https://on.cypress.io/config [stack trace lines] diff --git a/system-tests/__snapshots__/typescript_spec_support_spec.ts.js b/system-tests/__snapshots__/typescript_spec_support_spec.ts.js index 68023281820b..7b091eb4d44f 100644 --- a/system-tests/__snapshots__/typescript_spec_support_spec.ts.js +++ b/system-tests/__snapshots__/typescript_spec_support_spec.ts.js @@ -82,7 +82,7 @@ exports['e2e typescript in spec and support file spec fails with syntax error 1' Oops...we found an error preparing this test file: - cypress/e2e/typescript_syntax_error.cy.ts + > cypress/e2e/typescript_syntax_error.cy.ts The error was: diff --git a/system-tests/__snapshots__/web_security_spec.js b/system-tests/__snapshots__/web_security_spec.js index 00eded51c810..123bbdd5429d 100644 --- a/system-tests/__snapshots__/web_security_spec.js +++ b/system-tests/__snapshots__/web_security_spec.js @@ -232,7 +232,8 @@ exports['e2e web security / firefox / displays warning when firefox and chromeWe ──────────────────────────────────────────────────────────────────────────────────────────────────── Running: simple_passing.cy.js (1 of 1) -Your project has set the configuration option: \`chromeWebSecurity: false\` + +Your project has set the configuration option: chromeWebSecurity to false This option will not have an effect in Firefox. Tests that rely on web security being disabled will not run as expected. diff --git a/system-tests/lib/serverStub.ts b/system-tests/lib/serverStub.ts index 239732a3842a..e6acdff2f4a6 100644 --- a/system-tests/lib/serverStub.ts +++ b/system-tests/lib/serverStub.ts @@ -54,7 +54,7 @@ const routeHandlers = { postRun: { method: 'post', url: '/runs', - req: 'postRunRequest@2.4.0', + reqSchema: 'postRunRequest@2.4.0', resSchema: 'postRunResponse@2.2.0', res: (req, res) => { if (!req.body.specs) { @@ -69,7 +69,7 @@ const routeHandlers = { postRunInstance: { method: 'post', url: '/runs/:id/instances', - req: 'postRunInstanceRequest@2.1.0', + reqSchema: 'postRunInstanceRequest@2.1.0', resSchema: 'postRunInstanceResponse@2.1.0', res: (req, res) => { const response = { @@ -85,21 +85,21 @@ const routeHandlers = { postInstanceTests: { method: 'post', url: '/instances/:id/tests', - req: 'postInstanceTestsRequest@1.0.0', + reqSchema: 'postInstanceTestsRequest@1.0.0', resSchema: 'postInstanceTestsResponse@1.0.0', res: postInstanceTestsResponse, }, postInstanceResults: { method: 'post', url: '/instances/:id/results', - req: 'postInstanceResultsRequest@1.1.0', + reqSchema: 'postInstanceResultsRequest@1.1.0', resSchema: 'postInstanceResultsResponse@1.0.0', res: sendUploadUrls, }, putInstanceStdout: { method: 'put', url: '/instances/:id/stdout', - req: 'putInstanceStdoutRequest@1.0.0', + reqSchema: 'putInstanceStdoutRequest@1.0.0', res (req, res) { return res.sendStatus(200) }, @@ -184,7 +184,7 @@ const sendResponse = function (req, res, responseBody) { }) } -const ensureSchema = function (expectedRequestSchema, responseBody, expectedResponseSchema) { +const ensureSchema = function (onRequestBody, expectedRequestSchema, responseBody, expectedResponseSchema) { let reqName; let reqVersion if (expectedRequestSchema) { @@ -194,6 +194,10 @@ const ensureSchema = function (expectedRequestSchema, responseBody, expectedResp return async function (req, res) { const { body } = req + if (_.isFunction(onRequestBody)) { + onRequestBody(body) + } + try { if (expectedRequestSchema) { jsonSchemas.assertSchema(reqName, reqVersion)(body) @@ -268,7 +272,8 @@ const onServer = (routes) => { return _.each(routes, (route) => { return app[route.method](route.url, ensureSchema( - route.req, + route.onReqBody, + route.reqSchema, route.res, route.resSchema, )) diff --git a/system-tests/lib/system-tests.ts b/system-tests/lib/system-tests.ts index 5eafb161ef24..ac95e21620dd 100644 --- a/system-tests/lib/system-tests.ts +++ b/system-tests/lib/system-tests.ts @@ -449,8 +449,8 @@ const normalizeStdout = function (str, options: any = {}) { .replace(/^(\- )(\/.*\/packages\/server\/)(.*)$/gm, '$1$3') // Different browsers have different cross-origin error messages .replace(crossOriginErrorRe, '[Cross origin error message]') - // Replaces connection warning since Firefox sometimes takes longer to connect - .replace(/Still waiting to connect to Firefox, retrying in 1 second \(attempt .+\/.+\)/g, '') + // Replaces connection warning since Chrome or Firefox sometimes take longer to connect + .replace(/Still waiting to connect to .+, retrying in 1 second \(attempt .+\/.+\)\n/g, '') if (options.sanitizeScreenshotDimensions) { // screenshot dimensions @@ -929,7 +929,9 @@ const systemTests = { await settings.writeForTesting(e2ePath, ctx.settings) } - args = options.args || ['index.js'].concat(args) + const serverEntryFile = require.resolve('@packages/server') + + args = options.args || [serverEntryFile].concat(args) let stdout = '' let stderr = '' diff --git a/system-tests/projects/e2e/cypress/e2e/config_passing.cy.js b/system-tests/projects/e2e/cypress/e2e/config_passing.cy.js index c6a24f73f710..fdb17c89b9cf 100644 --- a/system-tests/projects/e2e/cypress/e2e/config_passing.cy.js +++ b/system-tests/projects/e2e/cypress/e2e/config_passing.cy.js @@ -44,7 +44,7 @@ describe('Cypress static methods + props', () => { context('.env', () => { // https://github.com/cypress-io/cypress/issues/4952 - it('doesn\'t die on ') }) }) diff --git a/system-tests/projects/no-specs-found/cypress.config.js b/system-tests/projects/no-specs-found/cypress.config.js deleted file mode 100644 index d1cc72b83e32..000000000000 --- a/system-tests/projects/no-specs-found/cypress.config.js +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = { - e2e: { - supportFile: false, - specPattern: '**/*.no-specs-found-with-this-pattern', - }, -} diff --git a/system-tests/projects/plugin-invalid-event-handler-error/cypress.config.js b/system-tests/projects/plugin-invalid-event-handler-error/cypress.config.js new file mode 100644 index 000000000000..5802b6c1cd3f --- /dev/null +++ b/system-tests/projects/plugin-invalid-event-handler-error/cypress.config.js @@ -0,0 +1,8 @@ +module.exports = { + e2e: { + supportFile: false, + setupNodeEvents: (on) => { + on('task', () => {}) + }, + }, +} diff --git a/system-tests/projects/plugin-invalid-event-handler-error/cypress/integration/app.cy.js b/system-tests/projects/plugin-invalid-event-handler-error/cypress/integration/app.cy.js new file mode 100644 index 000000000000..99a13400edf9 --- /dev/null +++ b/system-tests/projects/plugin-invalid-event-handler-error/cypress/integration/app.cy.js @@ -0,0 +1,3 @@ +it('passes', () => { + expect(true).to.be.true +}) diff --git a/system-tests/projects/plugin-no-function-return/cypress.config.js b/system-tests/projects/plugin-no-function-return/cypress.config.js new file mode 100644 index 000000000000..56b3bf83c097 --- /dev/null +++ b/system-tests/projects/plugin-no-function-return/cypress.config.js @@ -0,0 +1,9 @@ +module.exports = { + e2e: { + supportFile: false, + setupNodeEvents: { + foo: 'foo', + bar: 'bar', + }, + }, +} diff --git a/system-tests/projects/plugin-no-function-return/cypress/integration/app.cy.js b/system-tests/projects/plugin-no-function-return/cypress/integration/app.cy.js new file mode 100644 index 000000000000..582cc9815ade --- /dev/null +++ b/system-tests/projects/plugin-no-function-return/cypress/integration/app.cy.js @@ -0,0 +1 @@ +it('is true', () => {}) diff --git a/system-tests/projects/plugins-function-sync-error/cypress.config.js b/system-tests/projects/plugins-function-sync-error/cypress.config.js new file mode 100644 index 000000000000..184c8cfaf6c3 --- /dev/null +++ b/system-tests/projects/plugins-function-sync-error/cypress.config.js @@ -0,0 +1,12 @@ +module.exports = { + e2e: { + supportFile: false, + setupNodeEvents (on, config) { + const err = new Error('Function sync error from plugins file') + + err.name = 'FunctionSyncError' + + throw err + }, + }, +} diff --git a/system-tests/projects/plugins-function-sync-error/cypress/integration/app.cy.js b/system-tests/projects/plugins-function-sync-error/cypress/integration/app.cy.js new file mode 100644 index 000000000000..b3fc22ae77ba --- /dev/null +++ b/system-tests/projects/plugins-function-sync-error/cypress/integration/app.cy.js @@ -0,0 +1 @@ +it('passes', () => { }) diff --git a/system-tests/projects/plugins-root-sync-error/cypress.config.js b/system-tests/projects/plugins-root-sync-error/cypress.config.js new file mode 100644 index 000000000000..dca1d85b540d --- /dev/null +++ b/system-tests/projects/plugins-root-sync-error/cypress.config.js @@ -0,0 +1,5 @@ +const err = new Error('Root sync error from plugins file') + +err.name = 'RootSyncError' + +throw err diff --git a/system-tests/projects/plugins-root-sync-error/cypress/integration/app.cy.js b/system-tests/projects/plugins-root-sync-error/cypress/integration/app.cy.js new file mode 100644 index 000000000000..b3fc22ae77ba --- /dev/null +++ b/system-tests/projects/plugins-root-sync-error/cypress/integration/app.cy.js @@ -0,0 +1 @@ +it('passes', () => { }) diff --git a/system-tests/projects/vite-ct/cypress/component/support.spec.ts b/system-tests/projects/vite-ct/cypress/component/support.spec.ts new file mode 100644 index 000000000000..a164718c3c25 --- /dev/null +++ b/system-tests/projects/vite-ct/cypress/component/support.spec.ts @@ -0,0 +1,14 @@ +describe('Support files', () => { + it('can load a support file', () => { + const $body = Cypress.$('body') + + // Visual cue to help debug + const $supportNode = Cypress.$(`

Support file hasn't been loaded 😿

`) + + $body.append($supportNode) + + // @ts-ignore + expect(window.supportFileWasLoaded).to.be.true + $supportNode.text('Support file was loaded! ⚡️') + }) +}) diff --git a/system-tests/projects/vite-ct/cypress/plugins.js b/system-tests/projects/vite-ct/cypress/plugins.js new file mode 100644 index 000000000000..50fe518ab4d7 --- /dev/null +++ b/system-tests/projects/vite-ct/cypress/plugins.js @@ -0,0 +1,9 @@ +const { startDevServer } = require('@cypress/vite-dev-server') + +module.exports = (on) => { + on('dev-server:start', async (options) => { + return startDevServer({ + options, + }) + }) +} diff --git a/system-tests/projects/vite-ct/cypress/styles.css b/system-tests/projects/vite-ct/cypress/styles.css new file mode 100644 index 000000000000..1a425703201f --- /dev/null +++ b/system-tests/projects/vite-ct/cypress/styles.css @@ -0,0 +1,3 @@ +body{ + color:aquamarine +} \ No newline at end of file diff --git a/system-tests/projects/vite-ct/cypress/support.js b/system-tests/projects/vite-ct/cypress/support.js new file mode 100644 index 000000000000..192364e1f2b8 --- /dev/null +++ b/system-tests/projects/vite-ct/cypress/support.js @@ -0,0 +1,6 @@ +import '@testing-library/cypress/add-commands' +import './styles.css' + +before(() => { + window.supportFileWasLoaded = true +}) diff --git a/system-tests/projects/webpack-preprocessor-awesome-typescript-loader/cypress/e2e/failing.cy.ts b/system-tests/projects/webpack-preprocessor-awesome-typescript-loader/cypress/e2e/failing.cy.ts index 1c85959e31a2..8bad16995d92 100644 --- a/system-tests/projects/webpack-preprocessor-awesome-typescript-loader/cypress/e2e/failing.cy.ts +++ b/system-tests/projects/webpack-preprocessor-awesome-typescript-loader/cypress/e2e/failing.cy.ts @@ -1,8 +1,4 @@ -// https://github.com/cypress-io/cypress/issues/18069 -// This fixture project is copied to packages/server/.project and executed there. -// Because of that, the reference path is wrong here. -/// -/// +/// /** * This tests the error UI for a certain webpack preprocessor setup. @@ -20,6 +16,8 @@ import { fail, verify } from '../../../e2e/cypress/support/util' context('validation errors', function () { beforeEach(() => { + // @ts-ignore + window.top.__cySkipValidateConfig = true // @ts-ignore Cypress.config('isInteractive', true) }) @@ -30,7 +28,7 @@ context('validation errors', function () { }) verify(this, { - line: 29, + line: 27, column: 8, message: 'can only accept a string preset or', stack: ['throwErrBadArgs', 'From Your Spec Code:'], diff --git a/system-tests/projects/webpack-preprocessor-awesome-typescript-loader/package.json b/system-tests/projects/webpack-preprocessor-awesome-typescript-loader/package.json new file mode 100644 index 000000000000..e3a62248a153 --- /dev/null +++ b/system-tests/projects/webpack-preprocessor-awesome-typescript-loader/package.json @@ -0,0 +1,14 @@ +{ + "name": "@test-project/webpack-preprocessor-awesome-typescript-loader", + "version": "0.0.0-test", + "devDependencies": { + "@babel/core": "7.9.0", + "@babel/preset-env": "7.9.0", + "@cypress/webpack-preprocessor": "file:../../../npm/webpack-preprocessor", + "@types/node": "^12.11.1", + "awesome-typescript-loader": "5.2.1", + "babel-loader": "8.1.0", + "cypress": "file:../../../cli/build", + "typescript": "3.9.2" + } +} diff --git a/system-tests/projects/webpack-preprocessor-awesome-typescript-loader/tsconfig.json b/system-tests/projects/webpack-preprocessor-awesome-typescript-loader/tsconfig.json index fdd85d1d5ae4..a502e11358ec 100644 --- a/system-tests/projects/webpack-preprocessor-awesome-typescript-loader/tsconfig.json +++ b/system-tests/projects/webpack-preprocessor-awesome-typescript-loader/tsconfig.json @@ -6,7 +6,9 @@ "sourceMap": false, "inlineSourceMap": true, "inlineSources": false, - "typeRoots": ["../../../../cli/types"], - // "types": ["cypress"] + "types": [ + "cypress", + "node" + ] } -} +} \ No newline at end of file diff --git a/system-tests/projects/webpack-preprocessor-awesome-typescript-loader/yarn.lock b/system-tests/projects/webpack-preprocessor-awesome-typescript-loader/yarn.lock new file mode 100644 index 000000000000..38a5e5239f5b --- /dev/null +++ b/system-tests/projects/webpack-preprocessor-awesome-typescript-loader/yarn.lock @@ -0,0 +1,3194 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/code-frame@^7.16.7", "@babel/code-frame@^7.8.3": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" + integrity "sha1-REFra9diS5mPWxr11HCFbEATh4k= sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==" + dependencies: + "@babel/highlight" "^7.16.7" + +"@babel/compat-data@^7.16.4", "@babel/compat-data@^7.9.0": + version "7.17.0" + resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.0.tgz#86850b8597ea6962089770952075dcaabb8dba34" + integrity "sha1-hoULhZfqaWIIl3CVIHXcqruNujQ= sha512-392byTlpGWXMv4FbyWw3sAZ/FrW/DrwqLGXpy0mbyNe9Taqv1mg9yON5/o0cnr8XYCkFTZbC1eV+c+LAROgrng==" + +"@babel/core@7.9.0": + version "7.9.0" + resolved "https://registry.npmjs.org/@babel/core/-/core-7.9.0.tgz#ac977b538b77e132ff706f3b8a4dbad09c03c56e" + integrity "sha1-rJd7U4t34TL/cG87ik260JwDxW4= sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w==" + dependencies: + "@babel/code-frame" "^7.8.3" + "@babel/generator" "^7.9.0" + "@babel/helper-module-transforms" "^7.9.0" + "@babel/helpers" "^7.9.0" + "@babel/parser" "^7.9.0" + "@babel/template" "^7.8.6" + "@babel/traverse" "^7.9.0" + "@babel/types" "^7.9.0" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.1" + json5 "^2.1.2" + lodash "^4.17.13" + resolve "^1.3.2" + semver "^5.4.1" + source-map "^0.5.0" + +"@babel/generator@^7.17.0", "@babel/generator@^7.9.0": + version "7.17.0" + resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.17.0.tgz#7bd890ba706cd86d3e2f727322346ffdbf98f65e" + integrity "sha1-e9iQunBs2G0+L3JzIjRv/b+Y9l4= sha512-I3Omiv6FGOC29dtlZhkfXO6pgkmukJSlT26QjVvS1DGZe/NzSVCPG41X0tS21oZkJYlovfj9qDWgKP+Cn4bXxw==" + dependencies: + "@babel/types" "^7.17.0" + jsesc "^2.5.1" + source-map "^0.5.0" + +"@babel/helper-annotate-as-pure@^7.16.7": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz#bb2339a7534a9c128e3102024c60760a3a7f3862" + integrity "sha1-uyM5p1NKnBKOMQICTGB2Cjp/OGI= sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==" + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-builder-binary-assignment-operator-visitor@^7.16.7": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.7.tgz#38d138561ea207f0f69eb1626a418e4f7e6a580b" + integrity "sha1-ONE4Vh6iB/D2nrFiakGOT35qWAs= sha512-C6FdbRaxYjwVu/geKW4ZeQ0Q31AftgRcdSnZ5/jsH6BzCJbtvXvhpfkbkThYSuutZA7nCXpPR6AD9zd1dprMkA==" + dependencies: + "@babel/helper-explode-assignable-expression" "^7.16.7" + "@babel/types" "^7.16.7" + +"@babel/helper-compilation-targets@^7.16.7", "@babel/helper-compilation-targets@^7.8.7": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz#06e66c5f299601e6c7da350049315e83209d551b" + integrity "sha1-BuZsXymWAebH2jUASTFegyCdVRs= sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==" + dependencies: + "@babel/compat-data" "^7.16.4" + "@babel/helper-validator-option" "^7.16.7" + browserslist "^4.17.5" + semver "^6.3.0" + +"@babel/helper-create-regexp-features-plugin@^7.16.7": + version "7.17.0" + resolved "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.17.0.tgz#1dcc7d40ba0c6b6b25618997c5dbfd310f186fe1" + integrity "sha1-Hcx9QLoMa2slYYmXxdv9MQ8Yb+E= sha512-awO2So99wG6KnlE+TPs6rn83gCz5WlEePJDTnLEqbchMVrBeAujURVphRdigsk094VhvZehFoNOihSlcBjwsXA==" + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.7" + regexpu-core "^5.0.1" + +"@babel/helper-environment-visitor@^7.16.7": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz#ff484094a839bde9d89cd63cba017d7aae80ecd7" + integrity "sha1-/0hAlKg5venYnNY8ugF9eq6A7Nc= sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==" + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-explode-assignable-expression@^7.16.7": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.7.tgz#12a6d8522fdd834f194e868af6354e8650242b7a" + integrity "sha1-EqbYUi/dg08ZToaK9jVOhlAkK3o= sha512-KyUenhWMC8VrxzkGP0Jizjo4/Zx+1nNZhgocs+gLzyZyB8SHidhoq9KK/8Ato4anhwsivfkBLftky7gvzbZMtQ==" + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-function-name@^7.16.7": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz#f1ec51551fb1c8956bc8dd95f38523b6cf375f8f" + integrity "sha1-8exRVR+xyJVryN2V84Ujts83X48= sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==" + dependencies: + "@babel/helper-get-function-arity" "^7.16.7" + "@babel/template" "^7.16.7" + "@babel/types" "^7.16.7" + +"@babel/helper-get-function-arity@^7.16.7": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz#ea08ac753117a669f1508ba06ebcc49156387419" + integrity "sha1-6gisdTEXpmnxUIugbrzEkVY4dBk= sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==" + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-hoist-variables@^7.16.7": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz#86bcb19a77a509c7b77d0e22323ef588fa58c246" + integrity "sha1-hryxmnelCce3fQ4iMj71iPpYwkY= sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==" + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-member-expression-to-functions@^7.16.7": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.7.tgz#42b9ca4b2b200123c3b7e726b0ae5153924905b0" + integrity "sha1-QrnKSysgASPDt+cmsK5RU5JJBbA= sha512-VtJ/65tYiU/6AbMTDwyoXGPKHgTsfRarivm+YbB5uAzKUyuPjgZSgAFeG87FCigc7KNHu2Pegh1XIT3lXjvz3Q==" + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-module-imports@^7.16.7", "@babel/helper-module-imports@^7.8.3": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437" + integrity "sha1-JWEqgJGpmXBEYciiItDv7F0JFDc= sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==" + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-module-transforms@^7.16.7", "@babel/helper-module-transforms@^7.9.0": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz#7665faeb721a01ca5327ddc6bba15a5cb34b6a41" + integrity "sha1-dmX663IaAcpTJ93Gu6FaXLNLakE= sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng==" + dependencies: + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-module-imports" "^7.16.7" + "@babel/helper-simple-access" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + "@babel/helper-validator-identifier" "^7.16.7" + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.16.7" + "@babel/types" "^7.16.7" + +"@babel/helper-optimise-call-expression@^7.16.7": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.7.tgz#a34e3560605abbd31a18546bd2aad3e6d9a174f2" + integrity "sha1-o041YGBau9MaGFRr0qrT5tmhdPI= sha512-EtgBhg7rd/JcnpZFXpBy0ze1YRfdm7BnBX4uKMBd3ixa3RGAE002JZB66FJyNH7g0F38U05pXmA5P8cBh7z+1w==" + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz#aa3a8ab4c3cceff8e65eb9e73d87dc4ff320b2f5" + integrity "sha1-qjqKtMPM7/jmXrnnPYfcT/MgsvU= sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==" + +"@babel/helper-remap-async-to-generator@^7.16.8": + version "7.16.8" + resolved "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.8.tgz#29ffaade68a367e2ed09c90901986918d25e57e3" + integrity "sha1-Kf+q3mijZ+LtCckJAZhpGNJeV+M= sha512-fm0gH7Flb8H51LqJHy3HJ3wnE1+qtYR2A99K06ahwrawLdOFsCEWjZOrYricXJHoPSudNKxrMBUPEIPxiIIvBw==" + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.7" + "@babel/helper-wrap-function" "^7.16.8" + "@babel/types" "^7.16.8" + +"@babel/helper-replace-supers@^7.16.7": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.16.7.tgz#e9f5f5f32ac90429c1a4bdec0f231ef0c2838ab1" + integrity "sha1-6fX18yrJBCnBpL3sDyMe8MKDirE= sha512-y9vsWilTNaVnVh6xiJfABzsNpgDPKev9HnAgz6Gb1p6UUwf9NepdlsV7VXGCftJM+jqD5f7JIEubcpLjZj5dBw==" + dependencies: + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-member-expression-to-functions" "^7.16.7" + "@babel/helper-optimise-call-expression" "^7.16.7" + "@babel/traverse" "^7.16.7" + "@babel/types" "^7.16.7" + +"@babel/helper-simple-access@^7.16.7": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz#d656654b9ea08dbb9659b69d61063ccd343ff0f7" + integrity "sha1-1lZlS56gjbuWWbadYQY8zTQ/8Pc= sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==" + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-skip-transparent-expression-wrappers@^7.16.0": + version "7.16.0" + resolved "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz#0ee3388070147c3ae051e487eca3ebb0e2e8bb09" + integrity "sha1-DuM4gHAUfDrgUeSH7KPrsOLouwk= sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw==" + dependencies: + "@babel/types" "^7.16.0" + +"@babel/helper-split-export-declaration@^7.16.7": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz#0b648c0c42da9d3920d85ad585f2778620b8726b" + integrity "sha1-C2SMDELanTkg2FrVhfJ3hiC4cms= sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==" + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-validator-identifier@^7.16.7": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" + integrity "sha1-6MYCQ4xKgZV1EkPakDHRYH0kfK0= sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==" + +"@babel/helper-validator-option@^7.16.7": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23" + integrity "sha1-sgPOYs5f4VOJm2F8CJV96GDeTSM= sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==" + +"@babel/helper-wrap-function@^7.16.8": + version "7.16.8" + resolved "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.16.8.tgz#58afda087c4cd235de92f7ceedebca2c41274200" + integrity "sha1-WK/aCHxM0jXekvfO7evKLEEnQgA= sha512-8RpyRVIAW1RcDDGTA+GpPAwV22wXCfKOoM9bet6TLkGIFTkRQSkH1nMQ5Yet4MpoXe1ZwHPVtNasc2w0uZMqnw==" + dependencies: + "@babel/helper-function-name" "^7.16.7" + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.16.8" + "@babel/types" "^7.16.8" + +"@babel/helpers@^7.9.0": + version "7.17.2" + resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.2.tgz#23f0a0746c8e287773ccd27c14be428891f63417" + integrity "sha1-I/CgdGyOKHdzzNJ8FL5CiJH2NBc= sha512-0Qu7RLR1dILozr/6M0xgj+DFPmi6Bnulgm9M8BVa9ZCWxDqlSnqt3cf8IDPB5m45sVXUZ0kuQAgUrdSFFH79fQ==" + dependencies: + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.17.0" + "@babel/types" "^7.17.0" + +"@babel/highlight@^7.16.7": + version "7.16.10" + resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz#744f2eb81579d6eea753c227b0f570ad785aba88" + integrity "sha1-dE8uuBV51u6nU8InsPVwrXhauog= sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==" + dependencies: + "@babel/helper-validator-identifier" "^7.16.7" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@^7.16.7", "@babel/parser@^7.17.0", "@babel/parser@^7.9.0": + version "7.17.0" + resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.17.0.tgz#f0ac33eddbe214e4105363bb17c3341c5ffcc43c" + integrity "sha1-8Kwz7dviFOQQU2O7F8M0HF/8xDw= sha512-VKXSCQx5D8S04ej+Dqsr1CzYvvWgf20jIw2D+YhQCrIlr2UZGaDds23Y0xg75/skOxpLCRpUZvk/1EAVkGoDOw==" + +"@babel/plugin-proposal-async-generator-functions@^7.8.3": + version "7.16.8" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.8.tgz#3bdd1ebbe620804ea9416706cd67d60787504bc8" + integrity "sha1-O90eu+YggE6pQWcGzWfWB4dQS8g= sha512-71YHIvMuiuqWJQkebWJtdhQTfd4Q4mF76q2IX37uZPkG9+olBxsX+rH1vkhFto4UeJZ9dPY2s+mDvhDm1u2BGQ==" + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-remap-async-to-generator" "^7.16.8" + "@babel/plugin-syntax-async-generators" "^7.8.4" + +"@babel/plugin-proposal-dynamic-import@^7.8.3": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.7.tgz#c19c897eaa46b27634a00fee9fb7d829158704b2" + integrity "sha1-wZyJfqpGsnY0oA/un7fYKRWHBLI= sha512-I8SW9Ho3/8DRSdmDdH3gORdyUuYnk1m4cMxUAdu5oy4n3OfN8flDEH+d60iG7dUfi0KkYwSvoalHzzdRzpWHTg==" + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + +"@babel/plugin-proposal-json-strings@^7.8.3": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.7.tgz#9732cb1d17d9a2626a08c5be25186c195b6fa6e8" + integrity "sha1-lzLLHRfZomJqCMW+JRhsGVtvpug= sha512-lNZ3EEggsGY78JavgbHsK9u5P3pQaW7k4axlgFLYkMd7UBsiNahCITShLjNQschPyjtO6dADrL24757IdhBrsQ==" + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-json-strings" "^7.8.3" + +"@babel/plugin-proposal-nullish-coalescing-operator@^7.8.3": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.7.tgz#141fc20b6857e59459d430c850a0011e36561d99" + integrity "sha1-FB/CC2hX5ZRZ1DDIUKABHjZWHZk= sha512-aUOrYU3EVtjf62jQrCj63pYZ7k6vns2h/DQvHPWGmsJRYzWXZ6/AsfgpiRy6XiuIDADhJzP2Q9MwSMKauBQ+UQ==" + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + +"@babel/plugin-proposal-numeric-separator@^7.8.3": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.7.tgz#d6b69f4af63fb38b6ca2558442a7fb191236eba9" + integrity "sha1-1rafSvY/s4tsolWEQqf7GRI266k= sha512-vQgPMknOIgiuVqbokToyXbkY/OmmjAzr/0lhSIbG/KmnzXPGwW/AdhdKpi+O4X/VkWiWjnkKOBiqJrTaC98VKw==" + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + +"@babel/plugin-proposal-object-rest-spread@^7.9.0": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.16.7.tgz#94593ef1ddf37021a25bdcb5754c4a8d534b01d8" + integrity "sha1-lFk+8d3zcCGiW9y1dUxKjVNLAdg= sha512-3O0Y4+dw94HA86qSg9IHfyPktgR7q3gpNVAeiKQd+8jBKFaU5NQS1Yatgo4wY+UFNuLjvxcSmzcsHqrhgTyBUA==" + dependencies: + "@babel/compat-data" "^7.16.4" + "@babel/helper-compilation-targets" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.16.7" + +"@babel/plugin-proposal-optional-catch-binding@^7.8.3": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.7.tgz#c623a430674ffc4ab732fd0a0ae7722b67cb74cf" + integrity "sha1-xiOkMGdP/Eq3Mv0KCudyK2fLdM8= sha512-eMOH/L4OvWSZAE1VkHbr1vckLG1WUcHGJSLqqQwl2GaUqG6QjddvrOaTUMNYiv77H5IKPMZ9U9P7EaHwvAShfA==" + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + +"@babel/plugin-proposal-optional-chaining@^7.9.0": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.7.tgz#7cd629564724816c0e8a969535551f943c64c39a" + integrity "sha1-fNYpVkckgWwOipaVNVUflDxkw5o= sha512-eC3xy+ZrUcBtP7x+sq62Q/HYd674pPTb/77XZMb5wbDPGWIdUbSr4Agr052+zaUPSb+gGRnjxXfKFvx5iMJ+DA==" + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + +"@babel/plugin-proposal-unicode-property-regex@^7.4.4", "@babel/plugin-proposal-unicode-property-regex@^7.8.3": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.7.tgz#635d18eb10c6214210ffc5ff4932552de08188a2" + integrity "sha1-Y10Y6xDGIUIQ/8X/STJVLeCBiKI= sha512-QRK0YI/40VLhNVGIjRNAAQkEHws0cswSdFFjpFyt943YmJIU1da9uW63Iu6NFV6CxTZW5eTDCrwZUstBWgp/Rg==" + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-syntax-async-generators@^7.8.0", "@babel/plugin-syntax-async-generators@^7.8.4": + version "7.8.4" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + integrity "sha1-qYP7Gusuw/btBCohD2QOkOeG/g0= sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==" + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-dynamic-import@^7.8.0", "@babel/plugin-syntax-dynamic-import@^7.8.3": + version "7.8.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" + integrity "sha1-Yr+Ysto80h1iYVT8lu5bPLaOrLM= sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==" + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-json-strings@^7.8.0", "@babel/plugin-syntax-json-strings@^7.8.3": + version "7.8.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + integrity "sha1-AcohtmjNghjJ5kDLbdiMVBKyyWo= sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==" + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.0", "@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + integrity "sha1-Fn7XA2iIYIH3S1w2xlqIwDtm0ak= sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==" + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.10.4", "@babel/plugin-syntax-numeric-separator@^7.8.0": + version "7.10.4" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + integrity "sha1-ubBws+M1cM2f0Hun+pHA3Te5r5c= sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==" + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-object-rest-spread@^7.8.0", "@babel/plugin-syntax-object-rest-spread@^7.8.3": + version "7.8.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + integrity "sha1-YOIl7cvZimQDMqLnLdPmbxr1WHE= sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==" + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.8.0", "@babel/plugin-syntax-optional-catch-binding@^7.8.3": + version "7.8.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + integrity "sha1-YRGiZbz7Ag6579D9/X0mQCue1sE= sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==" + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-chaining@^7.8.0", "@babel/plugin-syntax-optional-chaining@^7.8.3": + version "7.8.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + integrity "sha1-T2nCq5UWfgGAzVM2YT+MV4j31Io= sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==" + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-top-level-await@^7.8.3": + version "7.14.5" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" + integrity "sha1-wc/a3DWmRiQAAfBhOCR7dBw02Uw= sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==" + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-transform-arrow-functions@^7.8.3": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.7.tgz#44125e653d94b98db76369de9c396dc14bef4154" + integrity "sha1-RBJeZT2UuY23Y2nenDltwUvvQVQ= sha512-9ffkFFMbvzTvv+7dTp/66xvZAWASuPD5Tl9LK3Z9vhOmANo6j94rik+5YMBt4CwHVMWLWpMsriIc2zsa3WW3xQ==" + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-async-to-generator@^7.8.3": + version "7.16.8" + resolved "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.8.tgz#b83dff4b970cf41f1b819f8b49cc0cfbaa53a808" + integrity "sha1-uD3/S5cM9B8bgZ+LScwM+6pTqAg= sha512-MtmUmTJQHCnyJVrScNzNlofQJ3dLFuobYn3mwOTKHnSCMtbNsqvF71GQmJfFjdrXSsAA7iysFmYWw4bXZ20hOg==" + dependencies: + "@babel/helper-module-imports" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-remap-async-to-generator" "^7.16.8" + +"@babel/plugin-transform-block-scoped-functions@^7.8.3": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.7.tgz#4d0d57d9632ef6062cdf354bb717102ee042a620" + integrity "sha1-TQ1X2WMu9gYs3zVLtxcQLuBCpiA= sha512-JUuzlzmF40Z9cXyytcbZEZKckgrQzChbQJw/5PuEHYeqzCsvebDx0K0jWnIIVcmmDOAVctCgnYs0pMcrYj2zJg==" + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-block-scoping@^7.8.3": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.7.tgz#f50664ab99ddeaee5bc681b8f3a6ea9d72ab4f87" + integrity "sha1-9QZkq5nd6u5bxoG486bqnXKrT4c= sha512-ObZev2nxVAYA4bhyusELdo9hb3H+A56bxH3FZMbEImZFiEDYVHXQSJ1hQKFlDnlt8G9bBrCZ5ZpURZUrV4G5qQ==" + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-classes@^7.9.0": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.7.tgz#8f4b9562850cd973de3b498f1218796eb181ce00" + integrity "sha1-j0uVYoUM2XPeO0mPEhh5brGBzgA= sha512-WY7og38SFAGYRe64BrjKf8OrE6ulEHtr5jEYaZMwox9KebgqPi67Zqz8K53EKk1fFEJgm96r32rkKZ3qA2nCWQ==" + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.7" + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-function-name" "^7.16.7" + "@babel/helper-optimise-call-expression" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-replace-supers" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + globals "^11.1.0" + +"@babel/plugin-transform-computed-properties@^7.8.3": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.7.tgz#66dee12e46f61d2aae7a73710f591eb3df616470" + integrity "sha1-Zt7hLkb2HSquenNxD1kes99hZHA= sha512-gN72G9bcmenVILj//sv1zLNaPyYcOzUho2lIJBMh/iakJ9ygCo/hEF9cpGb61SCMEDxbbyBoVQxrt+bWKu5KGw==" + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-destructuring@^7.8.3": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.16.7.tgz#ca9588ae2d63978a4c29d3f33282d8603f618e23" + integrity "sha1-ypWIri1jl4pMKdPzMoLYYD9hjiM= sha512-VqAwhTHBnu5xBVDCvrvqJbtLUa++qZaWC0Fgr2mqokBlulZARGyIvZDoqbPlPaKImQ9dKAcCzbv+ul//uqu70A==" + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-dotall-regex@^7.4.4", "@babel/plugin-transform-dotall-regex@^7.8.3": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.7.tgz#6b2d67686fab15fb6a7fd4bd895d5982cfc81241" + integrity "sha1-ay1naG+rFftqf9S9iV1Zgs/IEkE= sha512-Lyttaao2SjZF6Pf4vk1dVKv8YypMpomAbygW+mU5cYP3S5cWTfCJjG8xV6CFdzGFlfWK81IjL9viiTvpb6G7gQ==" + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-duplicate-keys@^7.8.3": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.7.tgz#2207e9ca8f82a0d36a5a67b6536e7ef8b08823c9" + integrity "sha1-Igfpyo+CoNNqWme2U25++LCII8k= sha512-03DvpbRfvWIXyK0/6QiR1KMTWeT6OcQ7tbhjrXyFS02kjuX/mu5Bvnh5SDSWHxyawit2g5aWhKwI86EE7GUnTw==" + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-exponentiation-operator@^7.8.3": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.7.tgz#efa9862ef97e9e9e5f653f6ddc7b665e8536fe9b" + integrity "sha1-76mGLvl+np5fZT9t3HtmXoU2/ps= sha512-8UYLSlyLgRixQvlYH3J2ekXFHDFLQutdy7FfFAMm3CPZ6q9wHCwnUyiXpQCe3gVVnQlHc5nsuiEVziteRNTXEA==" + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-for-of@^7.9.0": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.7.tgz#649d639d4617dff502a9a158c479b3b556728d8c" + integrity "sha1-ZJ1jnUYX3/UCqaFYxHmztVZyjYw= sha512-/QZm9W92Ptpw7sjI9Nx1mbcsWz33+l8kuMIQnDwgQBG5s3fAfQvkRjQ7NqXhtNcKOnPkdICmUHyCaWW06HCsqg==" + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-function-name@^7.8.3": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.7.tgz#5ab34375c64d61d083d7d2f05c38d90b97ec65cf" + integrity "sha1-WrNDdcZNYdCD19LwXDjZC5fsZc8= sha512-SU/C68YVwTRxqWj5kgsbKINakGag0KTgq9f2iZEXdStoAbOzLHEBRYzImmA6yFo8YZhJVflvXmIHUO7GWHmxxA==" + dependencies: + "@babel/helper-compilation-targets" "^7.16.7" + "@babel/helper-function-name" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-literals@^7.8.3": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.7.tgz#254c9618c5ff749e87cb0c0cef1a0a050c0bdab1" + integrity "sha1-JUyWGMX/dJ6HywwM7xoKBQwL2rE= sha512-6tH8RTpTWI0s2sV6uq3e/C9wPo4PTqqZps4uF0kzQ9/xPLFQtipynvmT1g/dOfEJ+0EQsHhkQ/zyRId8J2b8zQ==" + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-member-expression-literals@^7.8.3": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.7.tgz#6e5dcf906ef8a098e630149d14c867dd28f92384" + integrity "sha1-bl3PkG74oJjmMBSdFMhn3Sj5I4Q= sha512-mBruRMbktKQwbxaJof32LT9KLy2f3gH+27a5XSuXo6h7R3vqltl0PgZ80C8ZMKw98Bf8bqt6BEVi3svOh2PzMw==" + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-modules-amd@^7.9.0": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.7.tgz#b28d323016a7daaae8609781d1f8c9da42b13186" + integrity "sha1-so0yMBan2qroYJeB0fjJ2kKxMYY= sha512-KaaEtgBL7FKYwjJ/teH63oAmE3lP34N3kshz8mm4VMAw7U3PxjVwwUmxEFksbgsNUaO3wId9R2AVQYSEGRa2+g==" + dependencies: + "@babel/helper-module-transforms" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-modules-commonjs@^7.9.0": + version "7.16.8" + resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.8.tgz#cdee19aae887b16b9d331009aa9a219af7c86afe" + integrity "sha1-ze4ZquiHsWudMxAJqpohmvfIav4= sha512-oflKPvsLT2+uKQopesJt3ApiaIS2HW+hzHFcwRNtyDGieAeC/dIHZX8buJQ2J2X1rxGPy4eRcUijm3qcSPjYcA==" + dependencies: + "@babel/helper-module-transforms" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-simple-access" "^7.16.7" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-modules-systemjs@^7.9.0": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.16.7.tgz#887cefaef88e684d29558c2b13ee0563e287c2d7" + integrity "sha1-iHzvrviOaE0pVYwrE+4FY+KHwtc= sha512-DuK5E3k+QQmnOqBR9UkusByy5WZWGRxfzV529s9nPra1GE7olmxfqO2FHobEOYSPIjPBTr4p66YDcjQnt8cBmw==" + dependencies: + "@babel/helper-hoist-variables" "^7.16.7" + "@babel/helper-module-transforms" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-validator-identifier" "^7.16.7" + babel-plugin-dynamic-import-node "^2.3.3" + +"@babel/plugin-transform-modules-umd@^7.9.0": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.7.tgz#23dad479fa585283dbd22215bff12719171e7618" + integrity "sha1-I9rUefpYUoPb0iIVv/EnGRcedhg= sha512-EMh7uolsC8O4xhudF2F6wedbSHm1HHZ0C6aJ7K67zcDNidMzVcxWdGr+htW9n21klm+bOn+Rx4CBsAntZd3rEQ==" + dependencies: + "@babel/helper-module-transforms" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-named-capturing-groups-regex@^7.8.3": + version "7.16.8" + resolved "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.8.tgz#7f860e0e40d844a02c9dcf9d84965e7dfd666252" + integrity "sha1-f4YODkDYRKAsnc+dhJZeff1mYlI= sha512-j3Jw+n5PvpmhRR+mrgIh04puSANCk/T/UA3m3P1MjJkhlK906+ApHhDIqBQDdOgL/r1UYpz4GNclTXxyZrYGSw==" + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.16.7" + +"@babel/plugin-transform-new-target@^7.8.3": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.7.tgz#9967d89a5c243818e0800fdad89db22c5f514244" + integrity "sha1-mWfYmlwkOBjggA/a2J2yLF9RQkQ= sha512-xiLDzWNMfKoGOpc6t3U+etCE2yRnn3SM09BXqWPIZOBpL2gvVrBWUKnsJx0K/ADi5F5YC5f8APFfWrz25TdlGg==" + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-object-super@^7.8.3": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.7.tgz#ac359cf8d32cf4354d27a46867999490b6c32a94" + integrity "sha1-rDWc+NMs9DVNJ6RoZ5mUkLbDKpQ= sha512-14J1feiQVWaGvRxj2WjyMuXS2jsBkgB3MdSN5HuC2G5nRspa5RK9COcs82Pwy5BuGcjb+fYaUj94mYcOj7rCvw==" + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-replace-supers" "^7.16.7" + +"@babel/plugin-transform-parameters@^7.16.7", "@babel/plugin-transform-parameters@^7.8.7": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.7.tgz#a1721f55b99b736511cb7e0152f61f17688f331f" + integrity "sha1-oXIfVbmbc2URy34BUvYfF2iPMx8= sha512-AT3MufQ7zZEhU2hwOA11axBnExW0Lszu4RL/tAlUJBuNoRak+wehQW8h6KcXOcgjY42fHtDxswuMhMjFEuv/aw==" + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-property-literals@^7.8.3": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.7.tgz#2dadac85155436f22c696c4827730e0fe1057a55" + integrity "sha1-La2shRVUNvIsaWxIJ3MOD+EFelU= sha512-z4FGr9NMGdoIl1RqavCqGG+ZuYjfZ/hkCIeuH6Do7tXmSm0ls11nYVSJqFEUOSJbDab5wC6lRE/w6YjVcr6Hqw==" + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-regenerator@^7.8.7": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.16.7.tgz#9e7576dc476cb89ccc5096fff7af659243b4adeb" + integrity "sha1-nnV23EdsuJzMUJb/969lkkO0res= sha512-mF7jOgGYCkSJagJ6XCujSQg+6xC1M77/03K2oBmVJWoFGNUtnVJO4WHKJk3dnPC8HCcj4xBQP1Egm8DWh3Pb3Q==" + dependencies: + regenerator-transform "^0.14.2" + +"@babel/plugin-transform-reserved-words@^7.8.3": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.7.tgz#1d798e078f7c5958eec952059c460b220a63f586" + integrity "sha1-HXmOB498WVjuyVIFnEYLIgpj9YY= sha512-KQzzDnZ9hWQBjwi5lpY5v9shmm6IVG0U9pB18zvMu2i4H90xpT4gmqwPYsn8rObiadYe2M0gmgsiOIF5A/2rtg==" + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-shorthand-properties@^7.8.3": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.7.tgz#e8549ae4afcf8382f711794c0c7b6b934c5fbd2a" + integrity "sha1-6FSa5K/Pg4L3EXlMDHtrk0xfvSo= sha512-hah2+FEnoRoATdIb05IOXf+4GzXYTq75TVhIn1PewihbpyrNWUt2JbudKQOETWw6QpLe+AIUpJ5MVLYTQbeeUg==" + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-spread@^7.8.3": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.7.tgz#a303e2122f9f12e0105daeedd0f30fb197d8ff44" + integrity "sha1-owPiEi+fEuAQXa7t0PMPsZfY/0Q= sha512-+pjJpgAngb53L0iaA5gU/1MLXJIfXcYepLgXB3esVRf4fqmj8f2cxM3/FKaHsZms08hFQJkFccEWuIpm429TXg==" + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" + +"@babel/plugin-transform-sticky-regex@^7.8.3": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.7.tgz#c84741d4f4a38072b9a1e2e3fd56d359552e8660" + integrity "sha1-yEdB1PSjgHK5oeLj/VbTWVUuhmA= sha512-NJa0Bd/87QV5NZZzTuZG5BPJjLYadeSZ9fO6oOUoL4iQx+9EEuw/eEM92SrsT19Yc2jgB1u1hsjqDtH02c3Drw==" + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-template-literals@^7.8.3": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.7.tgz#f3d1c45d28967c8e80f53666fc9c3e50618217ab" + integrity "sha1-89HEXSiWfI6A9TZm/Jw+UGGCF6s= sha512-VwbkDDUeenlIjmfNeDX/V0aWrQH2QiVyJtwymVQSzItFDTpxfyJh3EVaQiS0rIN/CqbLGr0VcGmuwyTdZtdIsA==" + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-typeof-symbol@^7.8.4": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.7.tgz#9cdbe622582c21368bd482b660ba87d5545d4f7e" + integrity "sha1-nNvmIlgsITaL1IK2YLqH1VRdT34= sha512-p2rOixCKRJzpg9JB4gjnG4gjWkWa89ZoYUnl9snJ1cWIcTH/hvxZqfO+WjG6T8DRBpctEol5jw1O5rA8gkCokQ==" + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-unicode-regex@^7.8.3": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.7.tgz#0f7aa4a501198976e25e82702574c34cfebe9ef2" + integrity "sha1-D3qkpQEZiXbiXoJwJXTDTP6+nvI= sha512-oC5tYYKw56HO75KZVLQ+R/Nl3Hro9kf8iG0hXoaHP7tjAyCpvqBiSNe6vGrZni1Z6MggmUOC6A7VP7AVmw225Q==" + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/preset-env@7.9.0": + version "7.9.0" + resolved "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.9.0.tgz#a5fc42480e950ae8f5d9f8f2bbc03f52722df3a8" + integrity "sha1-pfxCSA6VCuj12fjyu8A/UnIt86g= sha512-712DeRXT6dyKAM/FMbQTV/FvRCms2hPCx+3weRjZ8iQVQWZejWWk1wwG6ViWMyqb/ouBbGOl5b6aCk0+j1NmsQ==" + dependencies: + "@babel/compat-data" "^7.9.0" + "@babel/helper-compilation-targets" "^7.8.7" + "@babel/helper-module-imports" "^7.8.3" + "@babel/helper-plugin-utils" "^7.8.3" + "@babel/plugin-proposal-async-generator-functions" "^7.8.3" + "@babel/plugin-proposal-dynamic-import" "^7.8.3" + "@babel/plugin-proposal-json-strings" "^7.8.3" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-proposal-numeric-separator" "^7.8.3" + "@babel/plugin-proposal-object-rest-spread" "^7.9.0" + "@babel/plugin-proposal-optional-catch-binding" "^7.8.3" + "@babel/plugin-proposal-optional-chaining" "^7.9.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.8.3" + "@babel/plugin-syntax-async-generators" "^7.8.0" + "@babel/plugin-syntax-dynamic-import" "^7.8.0" + "@babel/plugin-syntax-json-strings" "^7.8.0" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" + "@babel/plugin-syntax-numeric-separator" "^7.8.0" + "@babel/plugin-syntax-object-rest-spread" "^7.8.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" + "@babel/plugin-syntax-optional-chaining" "^7.8.0" + "@babel/plugin-syntax-top-level-await" "^7.8.3" + "@babel/plugin-transform-arrow-functions" "^7.8.3" + "@babel/plugin-transform-async-to-generator" "^7.8.3" + "@babel/plugin-transform-block-scoped-functions" "^7.8.3" + "@babel/plugin-transform-block-scoping" "^7.8.3" + "@babel/plugin-transform-classes" "^7.9.0" + "@babel/plugin-transform-computed-properties" "^7.8.3" + "@babel/plugin-transform-destructuring" "^7.8.3" + "@babel/plugin-transform-dotall-regex" "^7.8.3" + "@babel/plugin-transform-duplicate-keys" "^7.8.3" + "@babel/plugin-transform-exponentiation-operator" "^7.8.3" + "@babel/plugin-transform-for-of" "^7.9.0" + "@babel/plugin-transform-function-name" "^7.8.3" + "@babel/plugin-transform-literals" "^7.8.3" + "@babel/plugin-transform-member-expression-literals" "^7.8.3" + "@babel/plugin-transform-modules-amd" "^7.9.0" + "@babel/plugin-transform-modules-commonjs" "^7.9.0" + "@babel/plugin-transform-modules-systemjs" "^7.9.0" + "@babel/plugin-transform-modules-umd" "^7.9.0" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.8.3" + "@babel/plugin-transform-new-target" "^7.8.3" + "@babel/plugin-transform-object-super" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.8.7" + "@babel/plugin-transform-property-literals" "^7.8.3" + "@babel/plugin-transform-regenerator" "^7.8.7" + "@babel/plugin-transform-reserved-words" "^7.8.3" + "@babel/plugin-transform-shorthand-properties" "^7.8.3" + "@babel/plugin-transform-spread" "^7.8.3" + "@babel/plugin-transform-sticky-regex" "^7.8.3" + "@babel/plugin-transform-template-literals" "^7.8.3" + "@babel/plugin-transform-typeof-symbol" "^7.8.4" + "@babel/plugin-transform-unicode-regex" "^7.8.3" + "@babel/preset-modules" "^0.1.3" + "@babel/types" "^7.9.0" + browserslist "^4.9.1" + core-js-compat "^3.6.2" + invariant "^2.2.2" + levenary "^1.1.1" + semver "^5.5.0" + +"@babel/preset-modules@^0.1.3": + version "0.1.5" + resolved "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.5.tgz#ef939d6e7f268827e1841638dc6ff95515e115d9" + integrity "sha1-75Odbn8miCfhhBY43G/5VRXhFdk= sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==" + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" + "@babel/plugin-transform-dotall-regex" "^7.4.4" + "@babel/types" "^7.4.4" + esutils "^2.0.2" + +"@babel/runtime@^7.8.4": + version "7.17.2" + resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.2.tgz#66f68591605e59da47523c631416b18508779941" + integrity "sha1-ZvaFkWBeWdpHUjxjFBaxhQh3mUE= sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw==" + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/template@^7.16.7", "@babel/template@^7.8.6": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155" + integrity "sha1-jRJshwH95NZrJks+uj2W8HZm0VU= sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==" + dependencies: + "@babel/code-frame" "^7.16.7" + "@babel/parser" "^7.16.7" + "@babel/types" "^7.16.7" + +"@babel/traverse@^7.16.7", "@babel/traverse@^7.16.8", "@babel/traverse@^7.17.0", "@babel/traverse@^7.9.0": + version "7.17.0" + resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.17.0.tgz#3143e5066796408ccc880a33ecd3184f3e75cd30" + integrity "sha1-MUPlBmeWQIzMiAoz7NMYTz51zTA= sha512-fpFIXvqD6kC7c7PUNnZ0Z8cQXlarCLtCUpt2S1Dx7PjoRtCFffvOkHHSom+m5HIxMZn5bIBVb71lhabcmjEsqg==" + dependencies: + "@babel/code-frame" "^7.16.7" + "@babel/generator" "^7.17.0" + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-function-name" "^7.16.7" + "@babel/helper-hoist-variables" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + "@babel/parser" "^7.17.0" + "@babel/types" "^7.17.0" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.16.8", "@babel/types@^7.17.0", "@babel/types@^7.4.4", "@babel/types@^7.9.0": + version "7.17.0" + resolved "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz#a826e368bccb6b3d84acd76acad5c0d87342390b" + integrity "sha1-qCbjaLzLaz2ErNdqytXA2HNCOQs= sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==" + dependencies: + "@babel/helper-validator-identifier" "^7.16.7" + to-fast-properties "^2.0.0" + +"@cypress/request@^2.88.10": + version "2.88.10" + resolved "https://registry.npmjs.org/@cypress/request/-/request-2.88.10.tgz#b66d76b07f860d3a4b8d7a0604d020c662752cce" + integrity "sha1-tm12sH+GDTpLjXoGBNAgxmJ1LM4= sha512-Zp7F+R93N0yZyG34GutyTNr+okam7s/Fzc1+i3kcqOP8vk6OuajuE9qZJ6Rs+10/1JFtXFYMdyarnU1rZuJesg==" + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + http-signature "~1.3.6" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.5.0" + tunnel-agent "^0.6.0" + uuid "^8.3.2" + +"@cypress/webpack-preprocessor@file:../../../npm/webpack-preprocessor": + version "0.0.0-development" + dependencies: + bluebird "3.7.1" + debug "^4.3.2" + lodash "^4.17.20" + +"@cypress/xvfb@^1.2.4": + version "1.2.4" + resolved "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz#2daf42e8275b39f4aa53c14214e557bd14e7748a" + integrity "sha1-La9C6CdbOfSqU8FCFOVXvRTndIo= sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==" + dependencies: + debug "^3.1.0" + lodash.once "^4.1.1" + +"@types/json-schema@^7.0.5": + version "7.0.9" + resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" + integrity "sha1-l+3JA36gw4WFMgsolk3eOznkZg0= sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==" + +"@types/node@*": + version "17.0.16" + resolved "https://registry.npmjs.org/@types/node/-/node-17.0.16.tgz#e3733f46797b9df9e853ca9f719c8a6f7b84cd26" + integrity "sha1-43M/Rnl7nfnoU8qfcZyKb3uEzSY= sha512-ydLaGVfQOQ6hI1xK2A5nVh8bl0OGoIfYMxPWHqqYe9bTkWCfqiVvZoh2I/QF2sNSkZzZyROBoTefIEI+PB6iIA==" + +"@types/node@^12.11.1": + version "12.20.46" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.46.tgz#7e49dee4c54fd19584e6a9e0da5f3dc2e9136bc7" + integrity sha512-cPjLXj8d6anFPzFvOPxS3fvly3Shm5nTfl6g8X5smexixbuGUf7hfr21J5tX9JW+UPStp/5P5R8qrKL5IyVJ+A== + +"@types/node@^14.14.31": + version "14.18.10" + resolved "https://registry.npmjs.org/@types/node/-/node-14.18.10.tgz#774f43868964f3cfe4ced1f5417fe15818a4eaea" + integrity "sha1-d09Dholk88/kztH1QX/hWBik6uo= sha512-6iihJ/Pp5fsFJ/aEDGyvT4pHGmCpq7ToQ/yf4bl5SbVAvwpspYJ+v3jO7n8UyjhQVHTy+KNszOozDdv+O6sovQ==" + +"@types/sinonjs__fake-timers@8.1.1": + version "8.1.1" + resolved "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz#b49c2c70150141a15e0fa7e79cf1f92a72934ce3" + integrity "sha1-tJwscBUBQaFeD6fnnPH5KnKTTOM= sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==" + +"@types/sizzle@^2.3.2": + version "2.3.3" + resolved "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.3.tgz#ff5e2f1902969d305225a047c8a0fd5c915cebef" + integrity "sha1-/14vGQKWnTBSJaBHyKD9XJFc6+8= sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==" + +"@types/yauzl@^2.9.1": + version "2.9.2" + resolved "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.2.tgz#c48e5d56aff1444409e39fa164b0b4d4552a7b7a" + integrity "sha1-xI5dVq/xREQJ45+hZLC01FUqe3o= sha512-8uALY5LTvSuHgloDVUvWP3pIauILm+8/0pDMokuDYIoNsOkSwd5AiHBTSEJjKTDcZr5z8UpgOWZkxBF4iJftoA==" + dependencies: + "@types/node" "*" + +aggregate-error@^3.0.0: + version "3.1.0" + resolved "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" + integrity "sha1-kmcP9Q9TWb23o+DUDQ7DDFc3aHo= sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==" + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + +ajv-keywords@^3.5.2: + version "3.5.2" + resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + integrity "sha1-MfKdpatuANHC0yms97WSlhTVAU0= sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==" + +ajv@^6.12.4: + version "6.12.6" + resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity "sha1-uvWmLoArB9l3A0WG+MO69a3ybfQ= sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==" + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ansi-colors@^4.1.1: + version "4.1.1" + resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity "sha1-y7muJWv3UK8eqzRPIpqif+lLo0g= sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==" + +ansi-escapes@^4.3.0: + version "4.3.2" + resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity "sha1-ayKR0dt9mLZSHV8e+kLQ86n+tl4= sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==" + dependencies: + type-fest "^0.21.3" + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity "sha1-CCyyyJyf6GWaMRpTvWpNxTAdswQ= sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0= sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==" + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity "sha1-7dgDYornHATIWuegkG7a00tkiTc= sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==" + dependencies: + color-convert "^2.0.1" + +arch@^2.2.0: + version "2.2.0" + resolved "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz#1bc47818f305764f23ab3306b0bfc086c5a29d11" + integrity "sha1-G8R4GPMFdk8jqzMGsL/AhsWinRE= sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==" + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==" + +arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity "sha1-NgSLv/TntH4TZkQxbJlmnqWukfE= sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==" + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==" + +asn1@~0.2.3: + version "0.2.6" + resolved "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" + integrity "sha1-DTp7tuZOAqkMAwOzHykoaOoJoI0= sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==" + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==" + +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + integrity "sha1-SDFDxWeu7UeFdZwIZXhtx319LjE= sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==" + +async@^3.2.0: + version "3.2.3" + resolved "https://registry.npmjs.org/async/-/async-3.2.3.tgz#ac53dafd3f4720ee9e8a160628f18ea91df196c9" + integrity "sha1-rFPa/T9HIO6eihYGKPGOqR3xlsk= sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity "sha1-x57Zf380y48robyXkLzDZkdLS3k= sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + +at-least-node@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" + integrity "sha1-YCzUtG6EStTv/JKoARo8RuAjjcI= sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" + +atob@^2.1.2: + version "2.1.2" + resolved "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity "sha1-bZUX654DDSQ2ZmZR6GvZ9vE1M8k= sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" + +awesome-typescript-loader@5.2.1: + version "5.2.1" + resolved "https://registry.npmjs.org/awesome-typescript-loader/-/awesome-typescript-loader-5.2.1.tgz#a41daf7847515f4925cdbaa3075d61f289e913fc" + integrity "sha1-pB2veEdRX0klzbqjB11h8onpE/w= sha512-slv66OAJB8orL+UUaTI3pKlLorwIvS4ARZzYR9iJJyGsEgOqueMfOMdKySWzZ73vIkEe3fcwFgsKMg4d8zyb1g==" + dependencies: + chalk "^2.4.1" + enhanced-resolve "^4.0.0" + loader-utils "^1.1.0" + lodash "^4.17.5" + micromatch "^3.1.9" + mkdirp "^0.5.1" + source-map-support "^0.5.3" + webpack-log "^1.2.0" + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==" + +aws4@^1.8.0: + version "1.11.0" + resolved "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" + integrity "sha1-1h9G2DslGSUOJ4Ta9bCUeai0HFk= sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" + +babel-loader@8.1.0: + version "8.1.0" + resolved "https://registry.npmjs.org/babel-loader/-/babel-loader-8.1.0.tgz#c611d5112bd5209abe8b9fa84c3e4da25275f1c3" + integrity "sha1-xhHVESvVIJq+i5+oTD5NolJ18cM= sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw==" + dependencies: + find-cache-dir "^2.1.0" + loader-utils "^1.4.0" + mkdirp "^0.5.3" + pify "^4.0.1" + schema-utils "^2.6.5" + +babel-plugin-dynamic-import-node@^2.3.3: + version "2.3.3" + resolved "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" + integrity "sha1-hP2hnJduxcbe/vV/lCez3vZuF6M= sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==" + dependencies: + object.assign "^4.1.0" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity "sha1-6D46fj8wCzTLnYf2FfoMvzV2kO4= sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + +base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity "sha1-GxtEAWClv3rUC2UPCVljSBkDkwo= sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.npmjs.org/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity "sha1-e95c7RRbbVUakNuH+DxVi060io8= sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==" + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==" + dependencies: + tweetnacl "^0.14.3" + +big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity "sha1-ZfCvOC9Xi83HQr2cKB6cstd2gyg= sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==" + +blob-util@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz#3b4e3c281111bb7f11128518006cdc60b403a1eb" + integrity "sha1-O048KBERu38REoUYAGzcYLQDoes= sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==" + +bluebird@3.7.1: + version "3.7.1" + resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.7.1.tgz#df70e302b471d7473489acf26a93d63b53f874de" + integrity "sha1-33DjArRx10c0iazyapPWO1P4dN4= sha512-DdmyoGCleJnkbp3nkbxTLJ18rjDsE4yCggEwKNXkeV123sPNfOCYeDoeuOY+F2FrSjO1YXcTU+dsy96KMy+gcg==" + +bluebird@^3.7.2: + version "3.7.2" + resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity "sha1-nyKcFb4nJFT/qXOs4NvueaGww28= sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity "sha1-PH/L9SnYcibz0vUrlm/1Jx60Qd0= sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==" + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^2.3.1: + version "2.3.2" + resolved "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity "sha1-WXn9PxTNUxVl5fot8av/8d+u5yk= sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==" + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +browserslist@^4.17.5, browserslist@^4.19.1, browserslist@^4.9.1: + version "4.19.1" + resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz#4ac0435b35ab655896c31d53018b6dd5e9e4c9a3" + integrity "sha1-SsBDWzWrZViWwx1TAYtt1enkyaM= sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==" + dependencies: + caniuse-lite "^1.0.30001286" + electron-to-chromium "^1.4.17" + escalade "^3.1.1" + node-releases "^2.0.1" + picocolors "^1.0.0" + +buffer-crc32@~0.2.3: + version "0.2.13" + resolved "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + integrity "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity "sha1-KxRqb9cugLT1XSVfNe1Zo6mkG9U= sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + +buffer@^5.6.0: + version "5.7.1" + resolved "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity "sha1-umLnwTEzBTWCGXFghRqPZI6Z7tA= sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==" + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity "sha1-Cn9GQWgxyLZi7jb+TnxZ129marI= sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==" + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +cachedir@^2.3.0: + version "2.3.0" + resolved "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz#0c75892a052198f0b21c7c1804d8331edfcae0e8" + integrity "sha1-DHWJKgUhmPCyHHwYBNgzHt/K4Og= sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==" + +call-bind@^1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity "sha1-sdTonmiBGcPJqQOtMKuy9qkZvjw= sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==" + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +caniuse-lite@^1.0.30001286: + version "1.0.30001310" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001310.tgz#da02cd07432c9eece6992689d1b84ca18139eea8" + integrity "sha1-2gLNB0MsnuzmmSaJ0bhMoYE57qg= sha512-cb9xTV8k9HTIUA3GnPUJCk0meUnrHL5gy5QePfDjxHyNBcnzPzrHFv5GqfP7ue5b1ZyzZL0RJboD6hQlPXjhjg==" + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" + +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1: + version "2.4.2" + resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity "sha1-zUJUFnelQzPPVBpJEIwUMrRMlCQ= sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==" + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.1.0: + version "4.1.2" + resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity "sha1-qsTit3NKdAhnrrFr8CqtVWoeegE= sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==" + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +check-more-types@^2.24.0: + version "2.24.0" + resolved "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz#1420ffb10fd444dcfc79b43891bbfffd32a84600" + integrity "sha1-FCD/sQ/URNz8ebQ4kbv//TKoRgA= sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==" + +ci-info@^3.2.0: + version "3.3.0" + resolved "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz#b4ed1fb6818dea4803a55c623041f9165d2066b2" + integrity "sha1-tO0ftoGN6kgDpVxiMEH5Fl0gZrI= sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==" + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity "sha1-+TNprouafOAv1B+q0MqDAzGQxGM= sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==" + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + integrity "sha1-7oRy27Ep5yezHooQpCfe6d/kAIs= sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==" + +cli-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + integrity "sha1-JkMFp65JDR0Dvwybp8kl0XU68wc= sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==" + dependencies: + restore-cursor "^3.1.0" + +cli-table3@~0.6.1: + version "0.6.1" + resolved "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.1.tgz#36ce9b7af4847f288d3cdd081fbd09bf7bd237b8" + integrity "sha1-Ns6bevSEfyiNPN0IH70Jv3vSN7g= sha512-w0q/enDHhPLq44ovMGdQeeDLvwxwavsJX7oQGYt/LrBlYsyaxyDnp6z3QzFut/6kLLKnlcUVJLrpB7KBfgG/RA==" + dependencies: + string-width "^4.2.0" + optionalDependencies: + colors "1.4.0" + +cli-truncate@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7" + integrity "sha1-w54ovwXtzeW+O5iZKiLe7Vork8c= sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==" + dependencies: + slice-ansi "^3.0.0" + string-width "^4.2.0" + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==" + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity "sha1-u3GFBpDh8TZWfeYp0tVHHe2kweg= sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==" + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM= sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==" + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI= sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + +colorette@^2.0.16: + version "2.0.16" + resolved "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da" + integrity "sha1-cTua+E/bAAE58EVGvUqT9ipQhdo= sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==" + +colors@1.4.0: + version "1.4.0" + resolved "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" + integrity "sha1-xQSRR51MG9rtLJztMs98fcI2D3g= sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==" + +combined-stream@^1.0.6, combined-stream@~1.0.6: + version "1.0.8" + resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity "sha1-w9RaizT9cwYxoRCoolIGgrMdWn8= sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==" + dependencies: + delayed-stream "~1.0.0" + +commander@^5.1.0: + version "5.1.0" + resolved "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae" + integrity "sha1-Rqu9FlL44Fm92u+Zu9yyrZzxea4= sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==" + +common-tags@^1.8.0: + version "1.8.2" + resolved "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz#94ebb3c076d26032745fd54face7f688ef5ac9c6" + integrity "sha1-lOuzwHbSYDJ0X9VPrOf2iO9aycY= sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==" + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" + +component-emitter@^1.2.1: + version "1.3.0" + resolved "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity "sha1-FuQHD7qK4ptnnyIVhT7hgasuq8A= sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + +convert-source-map@^1.7.0: + version "1.8.0" + resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" + integrity "sha1-8zc8MtIbTXgN2ABFFGhPt5HKQ2k= sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==" + dependencies: + safe-buffer "~5.1.1" + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==" + +core-js-compat@^3.6.2: + version "3.21.0" + resolved "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.21.0.tgz#bcc86aa5a589cee358e7a7fa0a4979d5a76c3885" + integrity "sha1-vMhqpaWJzuNY56f6Ckl51adsOIU= sha512-OSXseNPSK2OPJa6GdtkMz/XxeXx8/CJvfhQWTqd6neuUraujcL4jVsjkLQz1OWnax8xVQJnRPe0V2jqNWORA+A==" + dependencies: + browserslist "^4.19.1" + semver "7.0.0" + +core-util-is@1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" + +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity "sha1-pgQtNjTCsn6TKPg3uWX6yDgI24U= sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + +cross-spawn@^7.0.0: + version "7.0.3" + resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity "sha1-9zqFudXUHQRVUcF34ogtSshXKKY= sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==" + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +"cypress@file:../../../cli": + version "0.0.0-development" + dependencies: + "@cypress/request" "^2.88.10" + "@cypress/xvfb" "^1.2.4" + "@types/node" "^14.14.31" + "@types/sinonjs__fake-timers" "8.1.1" + "@types/sizzle" "^2.3.2" + arch "^2.2.0" + blob-util "^2.0.2" + bluebird "^3.7.2" + buffer "^5.6.0" + cachedir "^2.3.0" + chalk "^4.1.0" + check-more-types "^2.24.0" + cli-cursor "^3.1.0" + cli-table3 "~0.6.1" + commander "^5.1.0" + common-tags "^1.8.0" + dayjs "^1.10.4" + debug "^4.3.2" + enquirer "^2.3.6" + eventemitter2 "^6.4.3" + execa "4.1.0" + executable "^4.1.1" + extract-zip "2.0.1" + figures "^3.2.0" + fs-extra "^9.1.0" + getos "^3.2.1" + is-ci "^3.0.0" + is-installed-globally "~0.4.0" + lazy-ass "^1.6.0" + listr2 "^3.8.3" + lodash "^4.17.21" + log-symbols "^4.0.0" + minimist "^1.2.5" + ospath "^1.2.2" + pretty-bytes "^5.6.0" + proxy-from-env "1.0.0" + request-progress "^3.0.0" + semver "^7.3.2" + supports-color "^8.1.1" + tmp "~0.2.1" + untildify "^4.0.0" + yauzl "^2.10.0" + +d@1, d@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" + integrity "sha1-hpgJU3LVjb7jRv/Qxwk/mfj561o= sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==" + dependencies: + es5-ext "^0.10.50" + type "^1.0.1" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==" + dependencies: + assert-plus "^1.0.0" + +dayjs@^1.10.4: + version "1.10.7" + resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.10.7.tgz#2cf5f91add28116748440866a0a1d26f3a6ce468" + integrity "sha1-LPX5Gt0oEWdIRAhmoKHSbzps5Gg= sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig==" + +debug@^2.2.0, debug@^2.3.3: + version "2.6.9" + resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8= sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==" + dependencies: + ms "2.0.0" + +debug@^3.1.0: + version "3.2.7" + resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity "sha1-clgLfpFF+zm2Z2+cXl+xALk0F5o= sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==" + dependencies: + ms "^2.1.1" + +debug@^4.1.0, debug@^4.1.1, debug@^4.3.2: + version "4.3.3" + resolved "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" + integrity "sha1-BCZuC3CpjURi5uKI44JZITMytmQ= sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==" + dependencies: + ms "2.1.2" + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==" + +define-properties@^1.1.3: + version "1.1.3" + resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity "sha1-z4jabL7ib+bbcJT2HYcMvYTO6fE= sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==" + dependencies: + object-keys "^1.0.12" + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==" + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity "sha1-dp66rz9KY6rTr56NMEybvnm/sOY= sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==" + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity "sha1-1Flono1lS6d+AqgX+HENcCyxbp0= sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==" + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity "sha1-3zrhmayt+31ECqrgsp4icrJOxhk= sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==" + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +electron-to-chromium@^1.4.17: + version "1.4.68" + resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.68.tgz#d79447b6bd1bec9183f166bb33d4bef0d5e4e568" + integrity "sha1-15RHtr0b7JGD8Wa7M9S+8NXk5Wg= sha512-cId+QwWrV8R1UawO6b9BR1hnkJ4EJPCPAr4h315vliHUtVUJDk39Sg1PMNnaWKfj5x+93ssjeJ9LKL6r8LaMiA==" + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity "sha1-6Bj9ac5cz8tARZT4QpY79TFkzDc= sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + +emojis-list@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + integrity "sha1-VXBmIEatKeLpFucariYKvf9Pang= sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==" + +end-of-stream@^1.1.0: + version "1.4.4" + resolved "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity "sha1-WuZKX0UFe682JuwU2gyl5LJDHrA= sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==" + dependencies: + once "^1.4.0" + +enhanced-resolve@^4.0.0: + version "4.5.0" + resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz#2f3cfd84dbe3b487f18f2db2ef1e064a571ca5ec" + integrity "sha1-Lzz9hNvjtIfxjy2y7x4GSlccpew= sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==" + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.5.0" + tapable "^1.0.0" + +enquirer@^2.3.6: + version "2.3.6" + resolved "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" + integrity "sha1-Kn/l3WNKHkElqXXsmU/1RW3Dc00= sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==" + dependencies: + ansi-colors "^4.1.1" + +errno@^0.1.3: + version "0.1.8" + resolved "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" + integrity "sha1-i7Ppx9Rjvkl2/4iPdrSAnrwugR8= sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==" + dependencies: + prr "~1.0.1" + +es5-ext@^0.10.35, es5-ext@^0.10.50: + version "0.10.53" + resolved "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz#93c5a3acfdbef275220ad72644ad02ee18368de1" + integrity "sha1-k8WjrP2+8nUiCtcmRK0C7hg2jeE= sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==" + dependencies: + es6-iterator "~2.0.3" + es6-symbol "~3.1.3" + next-tick "~1.0.0" + +es6-iterator@~2.0.3: + version "2.0.3" + resolved "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity "sha1-p96IkUGgWpSwhUQDstCg+/qY87c= sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==" + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-symbol@^3.1.1, es6-symbol@~3.1.3: + version "3.1.3" + resolved "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" + integrity "sha1-utXTwbzawoJp9MszHkMceKxwXRg= sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==" + dependencies: + d "^1.0.1" + ext "^1.1.2" + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity "sha1-2M/ccACWXFoBdLSoLqpcBVJ0LkA= sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity "sha1-dNLrTeC42hKTcRkQ1Qd1ubcQ72Q= sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + +eventemitter2@^6.4.3: + version "6.4.5" + resolved "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.5.tgz#97380f758ae24ac15df8353e0cc27f8b95644655" + integrity "sha1-lzgPdYriSsFd+DU+DMJ/i5VkRlU= sha512-bXE7Dyc1i6oQElDG0jMRZJrRAn9QR2xyyFGmBdZleNmyQX0FqGYmhZIrIrpPfm/w//LTo4tVQGOGQcGCb5q9uw==" + +execa@4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a" + integrity "sha1-TlSRrRVy8vF6d9OIxshXE1sihHo= sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==" + dependencies: + cross-spawn "^7.0.0" + get-stream "^5.0.0" + human-signals "^1.1.1" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.0" + onetime "^5.1.0" + signal-exit "^3.0.2" + strip-final-newline "^2.0.0" + +executable@^4.1.1: + version "4.1.1" + resolved "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz#41532bff361d3e57af4d763b70582db18f5d133c" + integrity "sha1-QVMr/zYdPlevTXY7cFgtsY9dEzw= sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==" + dependencies: + pify "^2.2.0" + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity "sha1-t3c14xXOMPa27/D4OwQVGiJEliI= sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==" + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +ext@^1.1.2: + version "1.6.0" + resolved "https://registry.npmjs.org/ext/-/ext-1.6.0.tgz#3871d50641e874cc172e2b53f919842d19db4c52" + integrity "sha1-OHHVBkHodMwXLitT+RmELRnbTFI= sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==" + dependencies: + type "^2.5.0" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==" + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==" + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extend@~3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity "sha1-+LETa0Bx+9jrFAr/hYsQGewpFfo= sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity "sha1-rQD+TcYSqSMuhxhxHcXLWrAoVUM= sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==" + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +extract-zip@2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a" + integrity "sha1-Zj3KVv5G34kNXxMe9KBtIruLoTo= sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==" + dependencies: + debug "^4.1.1" + get-stream "^5.1.0" + yauzl "^2.10.0" + optionalDependencies: + "@types/yauzl" "^2.9.1" + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==" + +extsprintf@^1.2.0: + version "1.4.1" + resolved "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" + integrity "sha1-jRcsBkhn8jXAyEpZaAbSeb9LzAc= sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==" + +fast-deep-equal@^3.1.1: + version "3.1.3" + resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity "sha1-On1WtVnWy8PrUSMlJE5hmmXGxSU= sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity "sha1-h0v2nG9ATCtdmcSBNBOZ/VWJJjM= sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + +fd-slicer@~1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" + integrity "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4= sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==" + dependencies: + pend "~1.2.0" + +figures@^3.2.0: + version "3.2.0" + resolved "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" + integrity "sha1-YlwYvSk8YE3EqN2y/r8MiDQXRq8= sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==" + dependencies: + escape-string-regexp "^1.0.5" + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==" + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +find-cache-dir@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" + integrity "sha1-jQ+UzRP+Q8bHwmGg2GEVypGMBfc= sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==" + dependencies: + commondir "^1.0.1" + make-dir "^2.0.0" + pkg-dir "^3.0.0" + +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity "sha1-SRafHXmTQwZG2mHsxa41XCHJe3M= sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==" + dependencies: + locate-path "^3.0.0" + +for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==" + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==" + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity "sha1-3M5SwF9kTymManq5Nr1yTO/786Y= sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==" + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==" + dependencies: + map-cache "^0.2.2" + +fs-extra@^9.1.0: + version "9.1.0" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" + integrity "sha1-WVRGDHZKjaIJS6NVS/g55rmnyG0= sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==" + dependencies: + at-least-node "^1.0.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity "sha1-FQStJSMVjKpA20onh8sBQRmU6k8= sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity "sha1-pWiZ0+o8m6uHS7l3O3xe3pL0iV0= sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + +gensync@^1.0.0-beta.1: + version "1.0.0-beta.2" + resolved "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity "sha1-MqbudsPX9S1GsrGuXZP+qFgKJeA= sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" + +get-intrinsic@^1.0.2: + version "1.1.1" + resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" + integrity "sha1-FfWfN2+FXERpY5SPDSTNNje0q8Y= sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==" + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + +get-stream@^5.0.0, get-stream@^5.1.0: + version "5.2.0" + resolved "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity "sha1-SWaheV7lrOZecGxLe+txJX1uItM= sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==" + dependencies: + pump "^3.0.0" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==" + +getos@^3.2.1: + version "3.2.1" + resolved "https://registry.npmjs.org/getos/-/getos-3.2.1.tgz#0134d1f4e00eb46144c5a9c0ac4dc087cbb27dc5" + integrity "sha1-ATTR9OAOtGFExanArE3Ah8uyfcU= sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==" + dependencies: + async "^3.2.0" + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==" + dependencies: + assert-plus "^1.0.0" + +glob@^7.1.3: + version "7.2.0" + resolved "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity "sha1-0VU1r3cy4C6Uj0xBYovZECk/YCM= sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +global-dirs@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz#70a76fe84ea315ab37b1f5576cbde7d48ef72686" + integrity "sha1-cKdv6E6jFas3sfVXbL3n1I73JoY= sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA==" + dependencies: + ini "2.0.0" + +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity "sha1-q4eVM4hooLq9hSV1gBjCp+uVxC4= sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0: + version "4.2.9" + resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96" + integrity "sha1-BBsF30V1Xlh6JJQiebnRExRuHJY= sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==" + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity "sha1-tdRU3CGZriJWmfNGfloH87lVuv0= sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s= sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + +has-symbols@^1.0.1: + version "1.0.2" + resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" + integrity "sha1-Fl0wcMADCXUqEjakeTMeOsVvFCM= sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==" + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==" + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity "sha1-bWHeldkd/Km5oCCJrThL/49it3E= sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==" + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==" + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity "sha1-ci18v8H2qoJB8W3YFOAR4fQeh5Y= sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==" + dependencies: + function-bind "^1.1.1" + +http-signature@~1.3.6: + version "1.3.6" + resolved "https://registry.npmjs.org/http-signature/-/http-signature-1.3.6.tgz#cb6fbfdf86d1c974f343be94e87f7fc128662cf9" + integrity "sha1-y2+/34bRyXTzQ76U6H9/wShmLPk= sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw==" + dependencies: + assert-plus "^1.0.0" + jsprim "^2.0.2" + sshpk "^1.14.1" + +human-signals@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" + integrity "sha1-xbHNFPUK6uCatsWf5jujOV/k36M= sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==" + +ieee754@^1.1.13: + version "1.2.1" + resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity "sha1-jrehCmP/8l0VpXsAFYbRd9Gw01I= sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity "sha1-Yk+PRJfWGbLZdoUx1Y9BIoVNclE= sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==" + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity "sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w= sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + +ini@2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5" + integrity "sha1-5f1Vbs3VcmvpePoQAYYurLCpS8U= sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==" + +invariant@^2.2.2: + version "2.2.4" + resolved "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + integrity "sha1-YQ88ksk1nOHbYW5TgAjSP/NRWOY= sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==" + dependencies: + loose-envify "^1.0.0" + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==" + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY= sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==" + dependencies: + kind-of "^6.0.0" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity "sha1-76ouqdqg16suoTqXsritUf776L4= sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + +is-ci@^3.0.0: + version "3.0.1" + resolved "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz#db6ecbed1bd659c43dac0f45661e7674103d1867" + integrity "sha1-227L7RvWWcQ9rA9FZh52dBA9GGc= sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==" + dependencies: + ci-info "^3.2.0" + +is-core-module@^2.8.1: + version "2.8.1" + resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211" + integrity "sha1-9Z/fynAdWHnQprEApAqhVgzichE= sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==" + dependencies: + has "^1.0.3" + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==" + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc= sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==" + dependencies: + kind-of "^6.0.0" + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity "sha1-Nm2CQN3kh8pRgjsaufB6EKeCUco= sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==" + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw= sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==" + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==" + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity "sha1-p0cPnkJnM9gb2B4RVSZOOjUHyrQ= sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==" + dependencies: + is-plain-object "^2.0.4" + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity "sha1-8Rb4Bk/pCz94RKOJl8C3UFEmnx0= sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + +is-installed-globally@~0.4.0: + version "0.4.0" + resolved "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz#9a0fd407949c30f86eb6959ef1b7994ed0b7b520" + integrity "sha1-mg/UB5ScMPhutpWe8beZTtC3tSA= sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==" + dependencies: + global-dirs "^3.0.0" + is-path-inside "^3.0.2" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==" + dependencies: + kind-of "^3.0.2" + +is-path-inside@^3.0.2: + version "3.0.3" + resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity "sha1-0jE2LlOgf/Kw4Op/7QSRYf/RYoM= sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==" + +is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity "sha1-LBY7P6+xtgbZ0Xko8FwqHDjgdnc= sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==" + dependencies: + isobject "^3.0.1" + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity "sha1-+sHj1TuXrVqdCunO8jifWBClwHc= sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==" + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" + +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + integrity "sha1-PybHaoCVk7Ur+i7LVxDtJ3m1Iqc= sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==" + +is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity "sha1-0YUOuXkezRjmGCzhKjDzlmNLsZ0= sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" + +isarray@1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==" + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity "sha1-TkMekrEalzFjaqH5yNHMvP2reN8= sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==" + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity "sha1-GSA/tZmR35jjoocFDUZHzerzJJk= sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity "sha1-peZUwuWi3rXyAdls77yoDA7y9RM= sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity "sha1-gFZNLkg9rPbo7yCWUKZ98/DCg6Q= sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + integrity "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==" + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity "sha1-afaofZUTq4u4/mO9sJecRI5oRmA= sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + +json-schema@0.4.0: + version "0.4.0" + resolved "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" + integrity "sha1-995M9u+rg4666zI2R0y7paGTCrU= sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" + +json5@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" + integrity "sha1-d5+wAYYE+oVOrL9iUhgNg1Q+Pb4= sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==" + dependencies: + minimist "^1.2.0" + +json5@^2.1.2: + version "2.2.0" + resolved "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" + integrity "sha1-Lf7+cgxrpSXZ69kJlQ8FFTFsiaM= sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==" + dependencies: + minimist "^1.2.5" + +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity "sha1-vFWyY0eTxnnsZAMJTrE2mKbsCq4= sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==" + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + +jsprim@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz#77ca23dbcd4135cd364800d22ff82c2185803d4d" + integrity "sha1-d8oj281BNc02SADSL/gsIYWAPU0= sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==" + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.4.0" + verror "1.10.0" + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==" + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity "sha1-IIE989cSkosgc3hpGkUGb65y3Vc= sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==" + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity "sha1-cpyR4thXt6QZofmqZWhcTDP1hF0= sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.3" + resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity "sha1-B8BQNKbDSfoG4k+jWqdttFgM5N0= sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + +lazy-ass@^1.6.0: + version "1.6.0" + resolved "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz#7999655e8646c17f089fdd187d150d3324d54513" + integrity "sha1-eZllXoZGwX8In90YfRUNMyTVRRM= sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==" + +leven@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" + integrity "sha1-d4kd6DQGTMy6gq54QrtrFKE+1/I= sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==" + +levenary@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/levenary/-/levenary-1.1.1.tgz#842a9ee98d2075aa7faeedbe32679e9205f46f77" + integrity "sha1-hCqe6Y0gdap/ru2+MmeekgX0b3c= sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ==" + dependencies: + leven "^3.1.0" + +listr2@^3.8.3: + version "3.14.0" + resolved "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz#23101cc62e1375fd5836b248276d1d2b51fdbe9e" + integrity "sha1-IxAcxi4Tdf1YNrJIJ20dK1H9vp4= sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==" + dependencies: + cli-truncate "^2.1.0" + colorette "^2.0.16" + log-update "^4.0.0" + p-map "^4.0.0" + rfdc "^1.3.0" + rxjs "^7.5.1" + through "^2.3.8" + wrap-ansi "^7.0.0" + +loader-utils@^1.1.0, loader-utils@^1.4.0: + version "1.4.0" + resolved "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" + integrity "sha1-xXm140yzSxp07cbB+za/o3HVphM= sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==" + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^1.0.1" + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity "sha1-2+w7OrdZdYBxtY/ln8QYca8hQA4= sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==" + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +lodash.once@^4.1.1: + version "4.1.1" + resolved "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" + integrity "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w= sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==" + +lodash@^4.17.13, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.5: + version "4.17.21" + resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity "sha1-Z5WRxWTDv/quhFTPCz3zcMPWkRw= sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + +log-symbols@^2.1.0: + version "2.2.0" + resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" + integrity "sha1-V0Dhxdbw39pK2TI7UzIQfva0xAo= sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==" + dependencies: + chalk "^2.0.1" + +log-symbols@^4.0.0: + version "4.1.0" + resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + integrity "sha1-P727lbRoOsn8eFER55LlWNSr1QM= sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==" + dependencies: + chalk "^4.1.0" + is-unicode-supported "^0.1.0" + +log-update@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz#589ecd352471f2a1c0c570287543a64dfd20e0a1" + integrity "sha1-WJ7NNSRx8qHAxXAodUOmTf0g4KE= sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==" + dependencies: + ansi-escapes "^4.3.0" + cli-cursor "^3.1.0" + slice-ansi "^4.0.0" + wrap-ansi "^6.2.0" + +loglevelnext@^1.0.1: + version "1.0.5" + resolved "https://registry.npmjs.org/loglevelnext/-/loglevelnext-1.0.5.tgz#36fc4f5996d6640f539ff203ba819641680d75a2" + integrity "sha1-NvxPWZbWZA9Tn/IDuoGWQWgNdaI= sha512-V/73qkPuJmx4BcBF19xPBr+0ZRVBhc4POxvZTZdMeXpJ4NItXSJ/MSwuFT0kQJlCbXvdlZoQQ/418bS1y9Jh6A==" + dependencies: + es6-symbol "^3.1.1" + object.assign "^4.1.0" + +loose-envify@^1.0.0: + version "1.4.0" + resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity "sha1-ce5R+nvkyuwaY4OffmgtgTLTDK8= sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==" + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity "sha1-bW/mVw69lqr5D8rR2vo7JWbbOpQ= sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==" + dependencies: + yallist "^4.0.0" + +make-dir@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" + integrity "sha1-XwMQ4YuL6JjMBwCSlaMK5B6R5vU= sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==" + dependencies: + pify "^4.0.1" + semver "^5.6.0" + +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==" + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==" + dependencies: + object-visit "^1.0.0" + +memory-fs@^0.5.0: + version "0.5.0" + resolved "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz#324c01288b88652966d161db77838720845a8e3c" + integrity "sha1-MkwBKIuIZSlm0WHbd4OHIIRajjw= sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==" + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity "sha1-UoI2KaFN0AyXcPtq1H3GMQ8sH2A= sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + +micromatch@^3.1.9: + version "3.1.10" + resolved "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity "sha1-cIWbyVyYQJUvNZoGij/En57PrCM= sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==" + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +mime-db@1.51.0: + version "1.51.0" + resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c" + integrity "sha1-2f9iRRhZsYNC2WCFDcPPt35j+ww= sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==" + +mime-types@^2.1.12, mime-types@~2.1.19: + version "2.1.34" + resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.34.tgz#5a712f9ec1503511a945803640fafe09d3793c24" + integrity "sha1-WnEvnsFQNRGpRYA2QPr+CdN5PCQ= sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==" + dependencies: + mime-db "1.51.0" + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity "sha1-ftLCzMyvhNP/y3pptXcR/CCDQBs= sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" + +minimatch@^3.0.4: + version "3.0.5" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz#4da8f1290ee0f0f8e83d60ca69f8f134068604a3" + integrity "sha1-TajxKQ7g8PjoPWDKafjxNAaGBKM= sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==" + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.0, minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity "sha1-Z9ZgFLZqaoqqDAg8X9WN9OTpdgI= sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + +mixin-deep@^1.2.0: + version "1.3.2" + resolved "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + integrity "sha1-ESC0PcNZp4Xc5ltVuC4lfM9HlWY= sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==" + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mkdirp@^0.5.1, mkdirp@^0.5.3: + version "0.5.5" + resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity "sha1-2Rzv1i0UNsoPQWIOJRKI1CAJne8= sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==" + dependencies: + minimist "^1.2.5" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk= sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + +ms@^2.1.1: + version "2.1.3" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity "sha1-V0yBOM4dK1hh8LRFedut1gxmFbI= sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity "sha1-uHqKpPwN6P5r6IiVs4mD/yZb0Rk= sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==" + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +next-tick@~1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" + integrity "sha1-yobR/ogoFpsBICCOPchCS524NCw= sha512-mc/caHeUcdjnC/boPWJefDr4KUIWQNv+tlnFnJd38QMou86QtxQzBJfxgGRzvx8jazYRqrVlaHarfO72uNxPOg==" + +node-releases@^2.0.1: + version "2.0.2" + resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz#7139fe71e2f4f11b47d4d2986aaf8c48699e0c01" + integrity "sha1-cTn+ceL08RtH1NKYaq+MSGmeDAE= sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==" + +npm-run-path@^4.0.0: + version "4.0.1" + resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity "sha1-t+zR5e1T2o43pV4cImnguX7XSOo= sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==" + dependencies: + path-key "^3.0.0" + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity "sha1-fn2Fi3gb18mRpBupde04EnVOmYw= sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==" + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-keys@^1.0.12, object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity "sha1-HEfyct8nfzsdrwYWd9nILiMixg4= sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==" + dependencies: + isobject "^3.0.0" + +object.assign@^4.1.0: + version "4.1.2" + resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" + integrity "sha1-DtVKNC7Os3s4/3brgxoOeIy2OUA= sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==" + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + has-symbols "^1.0.1" + object-keys "^1.1.1" + +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==" + dependencies: + isobject "^3.0.1" + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity "sha1-WDsap3WWHUsROsF9nFC6753Xa9E= sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==" + dependencies: + wrappy "1" + +onetime@^5.1.0: + version "5.1.2" + resolved "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity "sha1-0Oluu1awdHbfHdnEgG5SN5hcpF4= sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==" + dependencies: + mimic-fn "^2.1.0" + +ospath@^1.2.2: + version "1.2.2" + resolved "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz#1276639774a3f8ef2572f7fe4280e0ea4550c07b" + integrity "sha1-EnZjl3Sj+O8lcvf+QoDg6kVQwHs= sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==" + +p-limit@^2.0.0: + version "2.3.0" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity "sha1-PdM8ZHohT9//2DWTPrCG2g3CHbE= sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==" + dependencies: + p-try "^2.0.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity "sha1-Mi1poFwCZLJZl9n0DNiokasAZKQ= sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==" + dependencies: + p-limit "^2.0.0" + +p-map@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" + integrity "sha1-uy+Vpe2i7BaOySdOBqdHw+KQTSs= sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==" + dependencies: + aggregate-error "^3.0.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity "sha1-yyhoVA4xPWHeWPr741zpAE1VQOY= sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity "sha1-F0uSaHNVNP+8es5r9TpanhtcX18= sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity "sha1-WB9q3mWMu6ZaDTOA3ndTKVBU83U= sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity "sha1-+8EUtgykKzDZ2vWFjkvWi77bZzU= sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + +pend@~1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + integrity "sha1-elfrVQpng/kRUzH89GY9XI4AelA= sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==" + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity "sha1-y1vcdP8/UYkiNur3nWi8RFZKuBw= sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + +pify@^2.2.0: + version "2.3.0" + resolved "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity "sha1-7RQaasBDqEnqWISY59yosVMw6Qw= sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==" + +pify@^4.0.1: + version "4.0.1" + resolved "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity "sha1-SyzSXFDVmHNcUCkiJP2MbfQeMjE= sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" + +pkg-dir@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" + integrity "sha1-J0kCDyOe2ZCIGx9xIQ1R62UjvqM= sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==" + dependencies: + find-up "^3.0.0" + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==" + +pretty-bytes@^5.6.0: + version "5.6.0" + resolved "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb" + integrity "sha1-NWJW9kOAR3PIL2RyP+eMksYr6us= sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==" + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity "sha1-eCDZsWEgzFXKmud5JoCufbptf+I= sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + +proxy-from-env@1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz#33c50398f70ea7eb96d21f7b817630a55791c7ee" + integrity "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4= sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==" + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + integrity "sha1-0/wRS6BplaRexok/SEzrHXj19HY= sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==" + +psl@^1.1.28: + version "1.8.0" + resolved "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + integrity "sha1-kyb4vPsBOtzABf3/BWrM4CDlHCQ= sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity "sha1-tKIRaBW94vTh6mAjVOjHVWUQemQ= sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==" + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +punycode@^2.1.0, punycode@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity "sha1-tYsBCsQMIsVldhbI0sLALHv0eew= sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + +qs@~6.5.2: + version "6.5.3" + resolved "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" + integrity "sha1-Ou7/yRln7241wOSI70b7KWq3aq0= sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==" + +readable-stream@^2.0.1: + version "2.3.7" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity "sha1-Hsoc9xGu+BTAT2IlKjamL2yyO1c= sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +regenerate-unicode-properties@^10.0.1: + version "10.0.1" + resolved "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz#7f442732aa7934a3740c779bb9b3340dccc1fb56" + integrity "sha1-f0QnMqp5NKN0DHebubM0DczB+1Y= sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw==" + dependencies: + regenerate "^1.4.2" + +regenerate@^1.4.2: + version "1.4.2" + resolved "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" + integrity "sha1-uTRtiCfo9aMve6KWN9OYtpAUhIo= sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" + +regenerator-runtime@^0.13.4: + version "0.13.9" + resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" + integrity "sha1-iSV0Kpj/2QgUmI11Zq0wyjsmO1I= sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" + +regenerator-transform@^0.14.2: + version "0.14.5" + resolved "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz#c98da154683671c9c4dcb16ece736517e1b7feb4" + integrity "sha1-yY2hVGg2ccnE3LFuznNlF+G3/rQ= sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==" + dependencies: + "@babel/runtime" "^7.8.4" + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity "sha1-H07OJ+ALC2XgJHpoEOaoXYOldSw= sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==" + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +regexpu-core@^5.0.1: + version "5.0.1" + resolved "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.0.1.tgz#c531122a7840de743dcf9c83e923b5560323ced3" + integrity "sha1-xTESKnhA3nQ9z5yD6SO1VgMjztM= sha512-CriEZlrKK9VJw/xQGJpQM5rY88BtuL8DM+AEwvcThHilbxiTAy8vq4iJnd2tqq8wLmjbGZzP7ZcKFjbGkmEFrw==" + dependencies: + regenerate "^1.4.2" + regenerate-unicode-properties "^10.0.1" + regjsgen "^0.6.0" + regjsparser "^0.8.2" + unicode-match-property-ecmascript "^2.0.0" + unicode-match-property-value-ecmascript "^2.0.0" + +regjsgen@^0.6.0: + version "0.6.0" + resolved "https://registry.npmjs.org/regjsgen/-/regjsgen-0.6.0.tgz#83414c5354afd7d6627b16af5f10f41c4e71808d" + integrity "sha1-g0FMU1Sv19ZiexavXxD0HE5xgI0= sha512-ozE883Uigtqj3bx7OhL1KNbCzGyW2NQZPl6Hs09WTvCuZD5sTI4JY58bkbQWa/Y9hxIsvJ3M8Nbf7j54IqeZbA==" + +regjsparser@^0.8.2: + version "0.8.4" + resolved "https://registry.npmjs.org/regjsparser/-/regjsparser-0.8.4.tgz#8a14285ffcc5de78c5b95d62bbf413b6bc132d5f" + integrity "sha1-ihQoX/zF3njFuV1iu/QTtrwTLV8= sha512-J3LABycON/VNEu3abOviqGHuB/LOtOQj8SKmfP9anY5GfAVw/SPjwzSjxGjbZXIxbGfqTHtJw58C2Li/WkStmA==" + dependencies: + jsesc "~0.5.0" + +repeat-element@^1.1.2: + version "1.1.4" + resolved "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz#be681520847ab58c7568ac75fbfad28ed42d39e9" + integrity "sha1-vmgVIIR6tYx1aKx1+/rSjtQtOek= sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==" + +repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity "sha1-jcrkcOHIirwtYA//Sndihtp15jc= sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==" + +request-progress@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz#4ca754081c7fec63f505e4faa825aa06cd669dbe" + integrity "sha1-TKdUCBx/7GP1BeT6qCWqBs1mnb4= sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg==" + dependencies: + throttleit "^1.0.0" + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==" + +resolve@^1.3.2: + version "1.22.0" + resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" + integrity "sha1-XguMZ8Fd9XqJvbq+YDoALyFzEZg= sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==" + dependencies: + is-core-module "^2.8.1" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + integrity "sha1-OfZ8VLOnpYzqUjbZXPADQjljH34= sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==" + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity "sha1-uKSCXVvbH8P29Twrwz+BOIaBx7w= sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" + +rfdc@^1.3.0: + version "1.3.0" + resolved "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" + integrity "sha1-0LfEQasnINBdxM8m4ByJYx2doIs= sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==" + +rimraf@^3.0.0: + version "3.0.2" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity "sha1-8aVAK6YiCtUswSgrrBrjqkn9Bho= sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==" + dependencies: + glob "^7.1.3" + +rxjs@^7.5.1: + version "7.5.4" + resolved "https://registry.npmjs.org/rxjs/-/rxjs-7.5.4.tgz#3d6bd407e6b7ce9a123e76b1e770dc5761aa368d" + integrity "sha1-PWvUB+a3zpoSPnax53DcV2GqNo0= sha512-h5M3Hk78r6wAheJF0a5YahB1yRQKCsZ4MsGdZ5O9ETbVtjPcScGfrMmoOq7EBsCRzd4BDkvDJ7ogP8Sz5tTFiQ==" + dependencies: + tslib "^2.1.0" + +safe-buffer@^5.0.1, safe-buffer@^5.1.2: + version "5.2.1" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity "sha1-Hq+fqb2x/dTsdfWPnNtOa3gn7sY= sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + +safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity "sha1-mR7GnSluAxN0fVm9/St0XDX4go0= sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity "sha1-QKNmnzsHfR6UPURinhV91IAjvy4= sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==" + dependencies: + ret "~0.1.10" + +safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity "sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo= sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + +schema-utils@^2.6.5: + version "2.7.1" + resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" + integrity "sha1-HKTzLRskxZDCA7jnpQvw6kzTlNc= sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==" + dependencies: + "@types/json-schema" "^7.0.5" + ajv "^6.12.4" + ajv-keywords "^3.5.2" + +semver@7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" + integrity "sha1-XzyjV2HkfgWyBsba/yz4FPAxa44= sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==" + +semver@^5.4.1, semver@^5.5.0, semver@^5.6.0: + version "5.7.1" + resolved "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity "sha1-qVT5Ma66UI0we78Gnv8MAclhFvc= sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + +semver@^6.3.0: + version "6.3.0" + resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity "sha1-7gpkyK9ejO6mdoexM3YeG+y9HT0= sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + +semver@^7.3.2: + version "7.3.5" + resolved "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity "sha1-C2Ich5NI2JmOSw5L6Us/EuYBjvc= sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==" + dependencies: + lru-cache "^6.0.0" + +set-value@^2.0.0, set-value@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" + integrity "sha1-oY1AUw5vB95CKMfe/kInr4ytAFs= sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==" + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity "sha1-zNCvT4g1+9wmW4JGGq8MNmY/NOo= sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==" + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity "sha1-rhbxZE2HPsrYQ7AwexQzYtTEIXI= sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + +signal-exit@^3.0.2: + version "3.0.7" + resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity "sha1-qaF2f4r4QVURTqq9c/mSc8j1mtk= sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + +slice-ansi@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787" + integrity "sha1-Md3BCTCht+C2ewjJbC9Jt3p4l4c= sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==" + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + +slice-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" + integrity "sha1-UA6N0P1VsFgVCGJVsxla3ypF/ms= sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==" + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity "sha1-bBdfhv8UvbByRWPo88GwIaKGhTs= sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==" + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity "sha1-+VZHlIbyrNeXAGk/b3uAXkWrVuI= sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==" + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity "sha1-ZJIufFZbDhQgS6GqfWlkJ40lGC0= sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==" + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +source-map-resolve@^0.5.0: + version "0.5.3" + resolved "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" + integrity "sha1-GQhmvs51U+H48mei7oLGBrVQmho= sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==" + dependencies: + atob "^2.1.2" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-support@^0.5.3: + version "0.5.21" + resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity "sha1-BP58f54e0tZiIzwoyys1ufY/bk8= sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==" + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-url@^0.4.0: + version "0.4.1" + resolved "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" + integrity "sha1-CvZmBadFpaL5HPG7+KevvCg97FY= sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==" + +source-map@^0.5.0, source-map@^0.5.6: + version "0.5.7" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==" + +source-map@^0.6.0: + version "0.6.1" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity "sha1-dHIq8y6WFOnCh6jQu95IteLxomM= sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity "sha1-fLCd2jqGWFcFxks5pkZgOGguj+I= sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==" + dependencies: + extend-shallow "^3.0.0" + +sshpk@^1.14.1: + version "1.17.0" + resolved "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz#578082d92d4fe612b13007496e543fa0fbcbe4c5" + integrity "sha1-V4CC2S1P5hKxMAdJblQ/oPvL5MU= sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==" + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==" + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +string-width@^4.1.0, string-width@^4.2.0: + version "4.2.3" + resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity "sha1-JpxxF9J7Ba0uU2gwqOyJXvnG0BA= sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==" + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g= sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==" + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity "sha1-nibGPTD1NEPpSJSVshBdN7Z6hdk= sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==" + dependencies: + ansi-regex "^5.0.1" + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity "sha1-ibhS+y/L6Tb29LMYevsKEsGrWK0= sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity "sha1-4uaaRKyHcveKHsCzW2id9lMO/I8= sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==" + dependencies: + has-flag "^3.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo= sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==" + dependencies: + has-flag "^4.0.0" + +supports-color@^8.1.1: + version "8.1.1" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity "sha1-zW/BfihQDP9WwbhsCn/UpUpzAFw= sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==" + dependencies: + has-flag "^4.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity "sha1-btpL00SjyUrqN21MwxvHcxEDngk= sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" + +tapable@^1.0.0: + version "1.1.3" + resolved "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" + integrity "sha1-ofzMBrWNth/XpF2i2kT186Pme6I= sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==" + +throttleit@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz#9e785836daf46743145a5984b6268d828528ac6c" + integrity "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw= sha512-rkTVqu6IjfQ/6+uNuuc3sZek4CEYxTJom3IktzgdSxcZqdARuebbA/f4QmAxMQIxqq9ZLEUkSYqvuk1I6VKq4g==" + +through@^2.3.8: + version "2.3.8" + resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" + +tmp@~0.2.1: + version "0.2.1" + resolved "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" + integrity "sha1-hFf8MDfc9HGcJRNnoa9lAO4czxQ= sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==" + dependencies: + rimraf "^3.0.0" + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==" + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==" + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==" + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity "sha1-E8/dmzNlUvMLUfM6iuG0Knp1mc4= sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==" + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity "sha1-zZ+yoKodWhK0c72fuW+j3P9lreI= sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==" + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + +tslib@^2.1.0: + version "2.3.1" + resolved "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" + integrity "sha1-6KM1rdXOrlGqJh0ypJAVjvBC7wE= sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==" + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==" + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" + +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity "sha1-0mCiSwGYQ24TP6JqUkptZfo7Ljc= sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==" + +type@^1.0.1: + version "1.2.0" + resolved "https://registry.npmjs.org/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" + integrity "sha1-hI3XaY2vo+VKbEeedZxLw/GIR6A= sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==" + +type@^2.5.0: + version "2.6.0" + resolved "https://registry.npmjs.org/type/-/type-2.6.0.tgz#3ca6099af5981d36ca86b78442973694278a219f" + integrity "sha1-PKYJmvWYHTbKhreEQpc2lCeKIZ8= sha512-eiDBDOmkih5pMbo9OqsqPRGMljLodLcwd5XD5JbtNB0o89xZAwynY9EdCDsJU7LtcVCClu9DvM7/0Ep1hYX3EQ==" + +typescript@3.9.2: + version "3.9.2" + resolved "https://registry.npmjs.org/typescript/-/typescript-3.9.2.tgz#64e9c8e9be6ea583c54607677dd4680a1cf35db9" + integrity "sha1-ZOnI6b5upYPFRgdnfdRoChzzXbk= sha512-q2ktq4n/uLuNNShyayit+DTobV2ApPEo/6so68JaD5ojvc/6GClBipedB9zNWYxRSAlZXAe405Rlijzl6qDiSw==" + +unicode-canonical-property-names-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" + integrity "sha1-MBrNxSVjFnDTn2FG4Od/9rvevdw= sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==" + +unicode-match-property-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3" + integrity "sha1-VP0W4OyxZ88Ezx91a9zJLrp5dsM= sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==" + dependencies: + unicode-canonical-property-names-ecmascript "^2.0.0" + unicode-property-aliases-ecmascript "^2.0.0" + +unicode-match-property-value-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz#1a01aa57247c14c568b89775a54938788189a714" + integrity "sha1-GgGqVyR8FMVouJd1pUk4eIGJpxQ= sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw==" + +unicode-property-aliases-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz#0a36cb9a585c4f6abd51ad1deddb285c165297c8" + integrity "sha1-CjbLmlhcT2q9Ua0d7dsoXBZSl8g= sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ==" + +union-value@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" + integrity "sha1-C2/nuDWuzaYcbqTU8CwUIh4QmEc= sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==" + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^2.0.1" + +universalify@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" + integrity "sha1-daSYTv7cSwiXXFrrc/Uw0C3yVxc= sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==" + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +untildify@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" + integrity "sha1-K8lHuVNlJIfkYAlJ+wkeOujNkZs= sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==" + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity "sha1-mxpSWVIlhZ5V9mnZKPiMbFfyp34= sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==" + dependencies: + punycode "^2.1.0" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==" + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.npmjs.org/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity "sha1-1QyMrHmhn7wg8pEfVuuXP04QBw8= sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + +uuid@^3.1.0: + version "3.4.0" + resolved "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity "sha1-sj5DWK+oogL+ehAK8fX4g/AgB+4= sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + +uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity "sha1-gNW1ztJxu5r2xEXyGhoExgbO++I= sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==" + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +webpack-log@^1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/webpack-log/-/webpack-log-1.2.0.tgz#a4b34cda6b22b518dbb0ab32e567962d5c72a43d" + integrity "sha1-pLNM2msitRjbsKsy5WeWLVxypD0= sha512-U9AnICnu50HXtiqiDxuli5gLB5PGBo7VvcHx36jRZHwK4vzOYLbImqT4lwWwoMHdQWwEKw736fCHEekokTEKHA==" + dependencies: + chalk "^2.1.0" + log-symbols "^2.1.0" + loglevelnext "^1.0.1" + uuid "^3.1.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity "sha1-fGqN0KY2oDJ+ELWckobu6T8/UbE= sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==" + dependencies: + isexe "^2.0.0" + +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + integrity "sha1-6Tk7oHEC5skaOyIUePAlfNKFblM= sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==" + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity "sha1-Z+FFz/UQpqaYS98RUpEdadLrnkM= sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==" + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity "sha1-m7knkNnA7/7GO+c1GeEaNQGaOnI= sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + +yauzl@^2.10.0: + version "2.10.0" + resolved "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" + integrity "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk= sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==" + dependencies: + buffer-crc32 "~0.2.3" + fd-slicer "~1.1.0" diff --git a/system-tests/scripts/mocha-reporter-config.json b/system-tests/scripts/mocha-reporter-config.json index f7a0ee275adc..5b136ac89f3a 100644 --- a/system-tests/scripts/mocha-reporter-config.json +++ b/system-tests/scripts/mocha-reporter-config.json @@ -1,5 +1,5 @@ { - "reporterEnabled": "spec, mocha-junit-reporter, ../../system-tests/lib/performance-reporter.js", + "reporterEnabled": "spec, mocha-junit-reporter, ./lib/performance-reporter.js", "mochaJunitReporterReporterOptions": { "mochaFile": "/tmp/cypress/junit/test-results.[hash].xml" } diff --git a/system-tests/scripts/run.js b/system-tests/scripts/run.js index d89fefa78edf..fdd3058f2637 100644 --- a/system-tests/scripts/run.js +++ b/system-tests/scripts/run.js @@ -101,6 +101,8 @@ if (options.fgrep) { ) } +const configFilePath = path.join(__dirname, 'mocha-reporter-config.json') + commandAndArguments.args.push( '--timeout', options['inspect-brk'] ? '40000000' : '10000', @@ -109,7 +111,7 @@ commandAndArguments.args.push( '--reporter', 'mocha-multi-reporters', '--reporter-options', - 'configFile=../../system-tests/scripts/mocha-reporter-config.json', + `configFile=${configFilePath}`, '--extension=js,ts', // restore mocha 2.x behavior to force end process after spec run '--exit', @@ -158,6 +160,7 @@ if (options['cypress-inspect-brk']) { const cmd = `${commandAndArguments.command} ${ commandAndArguments.args.join(' ')}` +console.log('cwd:', process.cwd()) console.log('specfiles:', run) console.log('test command:') console.log(cmd) diff --git a/system-tests/test/config_spec.js b/system-tests/test/config_spec.js index 3d699ff42b9e..38abebb4756b 100644 --- a/system-tests/test/config_spec.js +++ b/system-tests/test/config_spec.js @@ -78,6 +78,7 @@ describe('e2e config', () => { it('throws error when multiple default config file are found in project', async function () { await Fixtures.scaffoldProject('pristine-with-e2e-testing') + const projectRoot = Fixtures.projectPath('pristine-with-e2e-testing') return fs.writeFile(path.join(projectRoot, 'cypress.config.ts'), 'export default {}').then(() => { @@ -91,6 +92,7 @@ describe('e2e config', () => { it('throws error when cypress.json is found in project and need migration', async function () { await Fixtures.scaffoldProject('pristine') + const projectRoot = Fixtures.projectPath('pristine') return fs.writeFile(path.join(projectRoot, 'cypress.json'), '{}').then(() => { @@ -104,7 +106,6 @@ describe('e2e config', () => { it('throws error when cypress.json is found in project and cypress.config.{ts|js} exists as well', async function () { await Fixtures.scaffoldProject('multiple-config-files-with-json') - Fixtures.projectPath('multiple-config-files-with-json') return systemTests.exec(this, { project: 'multiple-config-files-with-json', @@ -115,7 +116,6 @@ describe('e2e config', () => { it('throws an error if supportFile is set on the root level', async function () { await Fixtures.scaffoldProject('invalid-root-level-config') - Fixtures.projectPath('invalid-root-level-config') return systemTests.exec(this, { project: 'invalid-root-level-config', @@ -127,7 +127,6 @@ describe('e2e config', () => { it('throws an error if specPattern is set on the root level', async function () { await Fixtures.scaffoldProject('invalid-root-level-config') - Fixtures.projectPath('invalid-root-level-config') return systemTests.exec(this, { project: 'invalid-root-level-config', @@ -139,7 +138,6 @@ describe('e2e config', () => { it('throws an error if excludeSpecPattern is set on the root level', async function () { await Fixtures.scaffoldProject('invalid-root-level-config') - Fixtures.projectPath('invalid-root-level-config') return systemTests.exec(this, { project: 'invalid-root-level-config', @@ -151,7 +149,6 @@ describe('e2e config', () => { it('throws an error if baseUrl is set on the root level', async function () { await Fixtures.scaffoldProject('invalid-root-level-config') - Fixtures.projectPath('invalid-root-level-config') return systemTests.exec(this, { project: 'invalid-root-level-config', @@ -163,7 +160,6 @@ describe('e2e config', () => { it('throws an error if baseUrl is set on the component level', async function () { await Fixtures.scaffoldProject('invalid-root-level-config') - Fixtures.projectPath('invalid-root-level-config') return systemTests.exec(this, { project: 'invalid-root-level-config', diff --git a/system-tests/test/error_ui_spec.ts b/system-tests/test/error_ui_spec.ts index d0aa83dd9f5a..966fd622b3fd 100644 --- a/system-tests/test/error_ui_spec.ts +++ b/system-tests/test/error_ui_spec.ts @@ -20,9 +20,7 @@ describe('e2e error ui', function () { 'webpack-preprocessor', 'webpack-preprocessor-ts-loader', 'webpack-preprocessor-ts-loader-compiler-options', - // TODO: unskip this once we understand why it is failing - // @see https://github.com/cypress-io/cypress/issues/18497 - // 'webpack-preprocessor-awesome-typescript-loader', + 'webpack-preprocessor-awesome-typescript-loader', ] .forEach((project) => { systemTests.it(`handles sourcemaps in webpack for project: ${project}`, { diff --git a/system-tests/test/plugins_spec.js b/system-tests/test/plugins_spec.js index 424a9517eb9d..af584a832974 100644 --- a/system-tests/test/plugins_spec.js +++ b/system-tests/test/plugins_spec.js @@ -19,7 +19,8 @@ describe('e2e plugins', function () { expectedExitCode: 1, onRun (exec) { return exec().then(({ stdout }) => { - expect(stdout).to.include('The following error was thrown by a plugin. We stopped running your tests because a plugin crashed. Please check your e2e.setupNodeEvents method in `cypress.config.js`') + expect(stdout).to.include('We stopped running your tests because your config file crashed.') + expect(stdout).to.include('Your configFile threw an error from: cypress.config.js') expect(stdout).to.include('Error: Root async error from config file') }) }, @@ -153,6 +154,16 @@ describe('e2e plugins', function () { }) }) + it('fails when invalid event handler is registered', function () { + return systemTests.exec(this, { + spec: 'app.cy.js', + project: 'plugin-invalid-event-handler-error', + sanitizeScreenshotDimensions: true, + snapshot: true, + expectedExitCode: 1, + }) + }) + it('fails when setupNodeEvents is not a function', function () { return systemTests.exec(this, { spec: 'app.cy.js', @@ -163,6 +174,36 @@ describe('e2e plugins', function () { }) }) + it('fails when there is no function exported', function () { + return systemTests.exec(this, { + spec: 'app_spec.js', + project: 'plugin-no-function-return', + sanitizeScreenshotDimensions: true, + snapshot: true, + expectedExitCode: 1, + }) + }) + + it('fails when require throws synchronously', function () { + return systemTests.exec(this, { + spec: 'app_spec.js', + project: 'plugins-root-sync-error', + sanitizeScreenshotDimensions: true, + snapshot: true, + expectedExitCode: 1, + }) + }) + + it('fails when function throws synchronously', function () { + return systemTests.exec(this, { + spec: 'app_spec.js', + project: 'plugins-function-sync-error', + sanitizeScreenshotDimensions: true, + snapshot: true, + expectedExitCode: 1, + }) + }) + describe('preprocessor', function () { it('passes with working preprocessor', function () { return systemTests.exec(this, { diff --git a/system-tests/test/record_spec.js b/system-tests/test/record_spec.js index dae684a5a3a3..3987d52710ea 100644 --- a/system-tests/test/record_spec.js +++ b/system-tests/test/record_spec.js @@ -995,6 +995,38 @@ describe('e2e record', () => { }) }) + describe('create run 412', () => { + setupStubbedServer(createRoutes({ + postRun: { + reqSchema: 'postRunRequest@2.0.0', // force this to throw a schema error + onReqBody (body) { + _.extend(body, { + ci: null, + commit: null, + ciBuildId: null, + platform: null, + }) + }, + }, + })) + + it('errors and exits when request schema is invalid', function () { + return systemTests.exec(this, { + key: 'f858a2bc-b469-4e48-be67-0876339ee7e1', + spec: 'record_pass*', + configFile: 'cypress-with-project-id.config.js', + record: true, + snapshot: true, + expectedExitCode: 1, + }) + .then(() => { + const urls = getRequestUrls() + + expect(urls).to.be.empty + }) + }) + }) + describe('create run unknown 422', () => { setupStubbedServer(createRoutes({ postRun: { diff --git a/system-tests/test/specs_spec.js b/system-tests/test/specs_spec.js index 5b72505e1716..44776f6c573c 100644 --- a/system-tests/test/specs_spec.js +++ b/system-tests/test/specs_spec.js @@ -3,10 +3,35 @@ const systemTests = require('../lib/system-tests').default describe('e2e specs', () => { systemTests.setup() - it('failing when no specs found', function () { + it('failing when no specs found and default specPattern', function () { return systemTests.exec(this, { - project: 'no-specs-found', - testingType: 'e2e', + project: 'no-specs', + snapshot: true, + expectedExitCode: 1, + }) + }) + + it('failing when no specs found and custom specPattern', function () { + return systemTests.exec(this, { + project: 'no-specs-custom-pattern', + snapshot: true, + expectedExitCode: 1, + }) + }) + + it('failing when no specs found and spec pattern provided from CLI', function () { + return systemTests.exec(this, { + project: 'no-specs', + spec: 'does/not/exist/**notfound**', + snapshot: true, + expectedExitCode: 1, + }) + }) + + it('failing when no specs found with custom spec pattern and spec pattern provided from CLI', function () { + return systemTests.exec(this, { + project: 'no-specs-custom-pattern', + spec: 'does/not/exist/**notfound**', snapshot: true, expectedExitCode: 1, }) @@ -15,7 +40,6 @@ describe('e2e specs', () => { // @see https://github.com/cypress-io/cypress/issues/14226 it('handles the same integration and fixtures folders', function () { return systemTests.exec(this, { - testingType: 'e2e', project: 'same-fixtures-integration-folders', snapshot: false, expectedExitCode: 0, @@ -24,7 +48,6 @@ describe('e2e specs', () => { it('handles the fixtures folder being the subfolder of integration', function () { return systemTests.exec(this, { - testingType: 'e2e', project: 'fixture-subfolder-of-integration', snapshot: false, expectedExitCode: 0, diff --git a/system-tests/test/system_node_spec.js b/system-tests/test/system_node_spec.js index b5cd4d7f6b28..3f9a147c00e5 100644 --- a/system-tests/test/system_node_spec.js +++ b/system-tests/test/system_node_spec.js @@ -35,7 +35,8 @@ describe('e2e system node', () => { expect(stderr).to.contain('Plugin Electron version: undefined') }) - xit('uses bundled node when launching plugins file', async function () { + // TODO:(tgriesser) originally skipped this, not sure why + it.skip('uses bundled node when launching plugins file', async function () { const { stderr } = await systemTests.exec(this, { project: 'system-node', config: { diff --git a/system-tests/test/web_security_spec.js b/system-tests/test/web_security_spec.js index f23b0b8ca1a2..d2d820f08bf0 100644 --- a/system-tests/test/web_security_spec.js +++ b/system-tests/test/web_security_spec.js @@ -95,7 +95,7 @@ describe('e2e web security', () => { chromeWebSecurity: false, }, onStdout (stdout) { - expect(stdout).include('Your project has set the configuration option: `chromeWebSecurity: false`\n\nThis option will not have an effect in Firefox.') + expect(stdout).include('Your project has set the configuration option: chromeWebSecurity to false\n\nThis option will not have an effect in Firefox.') }, }) }) diff --git a/yarn.lock b/yarn.lock index b4fad51ddfd1..2db05db527ad 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9257,11 +9257,16 @@ resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.1.tgz#283f669ff76d7b8260df8ab7a4262cc83d988256" integrity sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg== -"@types/mocha@8.0.3", "@types/mocha@^8.0.2", "@types/mocha@^8.0.3": +"@types/mocha@8.0.3": version "8.0.3" resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-8.0.3.tgz#51b21b6acb6d1b923bbdc7725c38f9f455166402" integrity sha512-vyxR57nv8NfcU0GZu8EUXZLTbCMupIUwy95LJ6lllN+JRPG25CwMHoB1q5xKh8YKhQnHYRAn4yW2yuHbf/5xgg== +"@types/mocha@8.2.2", "@types/mocha@^8.0.2", "@types/mocha@^8.0.3": + version "8.2.2" + resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-8.2.2.tgz#91daa226eb8c2ff261e6a8cbf8c7304641e095e0" + integrity sha512-Lwh0lzzqT5Pqh6z61P3c3P5nm6fzQK/MMHl9UKeneAeInVflBSz1O2EkX6gM6xfJd7FBXBY5purtLx7fUiZ7Hw== + "@types/mocha@9.0.0": version "9.0.0" resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-9.0.0.tgz#3205bcd15ada9bc681ac20bef64e9e6df88fd297" @@ -9366,6 +9371,13 @@ resolved "https://registry.yarnpkg.com/@types/parsimmon/-/parsimmon-1.10.6.tgz#8fcf95990514d2a7624aa5f630c13bf2427f9cdd" integrity sha512-FwAQwMRbkhx0J6YELkwIpciVzCcgEqXEbIrIn3a2P5d3kGEHQ3wVhlN3YdVepYP+bZzCYO6OjmD4o9TGOZ40rA== +"@types/pixelmatch@^5.2.4": + version "5.2.4" + resolved "https://registry.yarnpkg.com/@types/pixelmatch/-/pixelmatch-5.2.4.tgz#ca145cc5ede1388c71c68edf2d1f5190e5ddd0f6" + integrity sha512-HDaSHIAv9kwpMN7zlmwfTv6gax0PiporJOipcrGsVNF3Ba+kryOZc0Pio5pn6NhisgWr7TaajlPEKTbTAypIBQ== + dependencies: + "@types/node" "*" + "@types/plist@^3.0.1": version "3.0.2" resolved "https://registry.yarnpkg.com/@types/plist/-/plist-3.0.2.tgz#61b3727bba0f5c462fe333542534a0c3e19ccb01" @@ -9374,6 +9386,13 @@ "@types/node" "*" xmlbuilder ">=11.0.1" +"@types/pngjs@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@types/pngjs/-/pngjs-6.0.1.tgz#c711ec3fbbf077fed274ecccaf85dd4673130072" + integrity sha512-J39njbdW1U/6YyVXvC9+1iflZghP8jgRf2ndYghdJb5xL49LYDB+1EuAxfbuJ2IBbWIL3AjHPQhgaTxT3YaYeg== + dependencies: + "@types/node" "*" + "@types/prettier@2.4.3": version "2.4.3" resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.4.3.tgz#a3c65525b91fca7da00ab1a3ac2b5a2a4afbffbf" @@ -9604,6 +9623,13 @@ resolved "https://registry.yarnpkg.com/@types/stringify-object/-/stringify-object-3.3.1.tgz#9ee394931e63468de0412a8e19c9f021a7d1d24d" integrity sha512-bpCBW0O+QrMLNFBY/+rkZtGzcYRmc2aTD8qYHOMNUmednqETfEZtFcGEA11l9xqbIeiT1PgXG0eq3zqayVzZSQ== +"@types/strip-ansi@^5.2.1": + version "5.2.1" + resolved "https://registry.yarnpkg.com/@types/strip-ansi/-/strip-ansi-5.2.1.tgz#acd97f1f091e332bb7ce697c4609eb2370fa2a92" + integrity sha512-1l5iM0LBkVU8JXxnIoBqNvg+yyOXxPeN6DNoD+7A9AN1B8FhYPSeIXgyNqwIqg1uzipTgVC2hmuDzB0u9qw/PA== + dependencies: + strip-ansi "*" + "@types/strip-bom@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@types/strip-bom/-/strip-bom-3.0.0.tgz#14a8ec3956c2e81edb7520790aecf21c290aebd2" @@ -11608,18 +11634,18 @@ ansi-regex@^6.0.1: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== -ansi-styles@3.2.1, ansi-styles@^3.2.0, ansi-styles@^3.2.1: +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= + +ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== dependencies: color-convert "^1.9.0" -ansi-styles@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" - integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= - ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" @@ -11627,6 +11653,11 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" +ansi-styles@^5: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" + integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== + ansi-styles@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.0.0.tgz#cb102df1c56f5123eab8b67cd7b98027a0279178" @@ -15329,7 +15360,7 @@ chokidar@3.5.1: optionalDependencies: fsevents "~2.3.1" -"chokidar@>=2.0.0 <4.0.0", "chokidar@>=3.0.0 <4.0.0", chokidar@^3.0.0, chokidar@^3.2.3, chokidar@^3.3.0, chokidar@^3.3.1, chokidar@^3.4.0, chokidar@^3.4.1, chokidar@^3.4.2, chokidar@^3.5.0, chokidar@^3.5.1, chokidar@^3.5.2, chokidar@^3.5.3: +chokidar@3.5.3, "chokidar@>=2.0.0 <4.0.0", "chokidar@>=3.0.0 <4.0.0", chokidar@^3.0.0, chokidar@^3.2.3, chokidar@^3.3.0, chokidar@^3.3.1, chokidar@^3.4.0, chokidar@^3.4.1, chokidar@^3.4.2, chokidar@^3.5.0, chokidar@^3.5.1, chokidar@^3.5.2, chokidar@^3.5.3: version "3.5.3" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== @@ -15420,7 +15451,7 @@ ci-info@^2.0.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== -ci-info@^3.1.1: +ci-info@^3.2.0: version "3.3.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.0.tgz#b4ed1fb6818dea4803a55c623041f9165d2066b2" integrity sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw== @@ -17825,10 +17856,10 @@ debounce@^1.2.0: resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.1.tgz#38881d8f4166a5c5848020c11827b834bcb3e0a5" integrity sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug== -debug@*, debug@4, debug@4.3.2, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@~4.3.1: - version "4.3.2" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" - integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== +debug@*, debug@4, debug@4.3.3, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@~4.3.1: + version "4.3.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" + integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== dependencies: ms "2.1.2" @@ -17888,6 +17919,13 @@ debug@4.3.1: dependencies: ms "2.1.2" +debug@4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" + integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== + dependencies: + ms "2.1.2" + debug@^3.0.0, debug@^3.1.0, debug@^3.1.1, debug@^3.2.5, debug@^3.2.6, debug@^3.2.7: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" @@ -20821,7 +20859,7 @@ fast-glob@^2.0.2, fast-glob@^2.2.6: merge2 "^1.2.3" micromatch "^3.1.10" -fast-glob@^3.0.3, fast-glob@^3.1.1, fast-glob@^3.2.4, fast-glob@^3.2.5, fast-glob@^3.2.6, fast-glob@^3.2.7: +fast-glob@^3.0.3, fast-glob@^3.1.1, fast-glob@^3.2.4, fast-glob@^3.2.5, fast-glob@^3.2.6, fast-glob@^3.2.7, fast-glob@^3.2.9: version "3.2.11" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== @@ -22745,16 +22783,16 @@ globby@8.0.2: pify "^3.0.0" slash "^1.0.0" -globby@^11.0.0, globby@^11.0.1, globby@^11.0.2, globby@^11.0.3, globby@^11.0.4: - version "11.0.4" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5" - integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg== +globby@^11.0.0, globby@^11.0.1, globby@^11.0.2, globby@^11.0.3, globby@^11.0.4, globby@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== dependencies: array-union "^2.1.0" dir-glob "^3.0.1" - fast-glob "^3.1.1" - ignore "^5.1.4" - merge2 "^1.3.0" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" slash "^3.0.0" globby@^6.1.0: @@ -24139,7 +24177,7 @@ ignore@^4.0.3, ignore@^4.0.6: resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== -ignore@^5.1.1, ignore@^5.1.4: +ignore@^5.1.1, ignore@^5.1.4, ignore@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== @@ -24756,12 +24794,12 @@ is-ci@^1.0.10: dependencies: ci-info "^1.5.0" -is-ci@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.0.tgz#c7e7be3c9d8eef7d0fa144390bd1e4b88dc4c994" - integrity sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ== +is-ci@^3.0.0, is-ci@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.1.tgz#db6ecbed1bd659c43dac0f45661e7674103d1867" + integrity sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ== dependencies: - ci-info "^3.1.1" + ci-info "^3.2.0" is-cidr@^3.0.0: version "3.1.1" @@ -26520,7 +26558,7 @@ js-yaml@4.0.0: dependencies: argparse "^2.0.1" -js-yaml@^4.0.0, js-yaml@^4.1.0: +js-yaml@4.1.0, js-yaml@^4.0.0, js-yaml@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== @@ -28351,14 +28389,7 @@ log-symbols@4.0.0: dependencies: chalk "^4.0.0" -log-symbols@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18" - integrity sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg= - dependencies: - chalk "^1.0.0" - -log-symbols@^4.0.0, log-symbols@^4.1.0: +log-symbols@4.1.0, log-symbols@^4.0.0, log-symbols@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== @@ -28366,6 +28397,13 @@ log-symbols@^4.0.0, log-symbols@^4.1.0: chalk "^4.1.0" is-unicode-supported "^0.1.0" +log-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18" + integrity sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg= + dependencies: + chalk "^1.0.0" + log-update@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/log-update/-/log-update-2.3.0.tgz#88328fd7d1ce7938b29283746f0b1bc126b24708" @@ -29034,7 +29072,7 @@ merge-stream@^2.0.0: resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== -merge2@^1.2.3, merge2@^1.3.0: +merge2@^1.2.3, merge2@^1.3.0, merge2@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== @@ -29747,7 +29785,37 @@ mocha@7.1.2, mocha@^7.1.0: yargs-parser "13.1.2" yargs-unparser "1.6.0" -mocha@>=1.13.0, mocha@^8.1.1, mocha@^8.1.3: +mocha@>=1.13.0: + version "9.2.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-9.2.0.tgz#2bfba73d46e392901f877ab9a47b7c9c5d0275cc" + integrity sha512-kNn7E8g2SzVcq0a77dkphPsDSN7P+iYkqE0ZsGCYWRsoiKjOt+NvXfaagik8vuDa6W5Zw3qxe8Jfpt5qKf+6/Q== + dependencies: + "@ungap/promise-all-settled" "1.1.2" + ansi-colors "4.1.1" + browser-stdout "1.3.1" + chokidar "3.5.3" + debug "4.3.3" + diff "5.0.0" + escape-string-regexp "4.0.0" + find-up "5.0.0" + glob "7.2.0" + growl "1.10.5" + he "1.2.0" + js-yaml "4.1.0" + log-symbols "4.1.0" + minimatch "3.0.4" + ms "2.1.3" + nanoid "3.2.0" + serialize-javascript "6.0.0" + strip-json-comments "3.1.1" + supports-color "8.1.1" + which "2.0.2" + workerpool "6.2.0" + yargs "16.2.0" + yargs-parser "20.2.4" + yargs-unparser "2.0.0" + +mocha@^8.1.1, mocha@^8.1.3: version "8.3.1" resolved "https://registry.yarnpkg.com/mocha/-/mocha-8.3.1.tgz#b9eda6da1eb8cb8d29860a9c2205de5b8a076560" integrity sha512-5SBMxANWqOv5bw3Hx+HVgaWlcWcFEQDUdaUAr1AUU+qwtx6cowhn7gEDT/DwQP7uYxnvShdUOVLbTYAHOEGfDQ== @@ -30092,11 +30160,16 @@ nanoid@3.1.20: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.20.tgz#badc263c6b1dcf14b71efaa85f6ab4c1d6cfc788" integrity sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw== -nanoid@^3.1.16, nanoid@^3.1.22, nanoid@^3.2.0: +nanoid@3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c" integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA== +nanoid@^3.1.16, nanoid@^3.1.22, nanoid@^3.2.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35" + integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw== + nanomatch@^1.2.9: version "1.2.13" resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" @@ -32776,6 +32849,11 @@ pngjs@^4.0.1: resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-4.0.1.tgz#f803869bb2fc1bfe1bf99aa4ec21c108117cfdbe" integrity sha512-rf5+2/ioHeQxR6IxuYNYGFytUyG3lma/WW1nsmjeHlWwtb2aByla6dkVc8pmJ9nplzkTA0q2xx7mMWrOTqT4Gg== +pngjs@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-6.0.0.tgz#ca9e5d2aa48db0228a52c419c3308e87720da821" + integrity sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg== + pnp-webpack-plugin@1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.5.0.tgz#62a1cd3068f46d564bb33c56eb250e4d586676eb" @@ -37480,6 +37558,13 @@ serialize-javascript@5.0.1, serialize-javascript@^5.0.1: dependencies: randombytes "^2.1.0" +serialize-javascript@6.0.0, serialize-javascript@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" + integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== + dependencies: + randombytes "^2.1.0" + serialize-javascript@^1.7.0: version "1.9.1" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.9.1.tgz#cfc200aef77b600c47da9bb8149c943e798c2fdb" @@ -37497,13 +37582,6 @@ serialize-javascript@^4.0.0: dependencies: randombytes "^2.1.0" -serialize-javascript@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" - integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== - dependencies: - randombytes "^2.1.0" - serve-favicon@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/serve-favicon/-/serve-favicon-2.5.0.tgz#935d240cdfe0f5805307fdfe967d88942a2cbcf0" @@ -39194,6 +39272,13 @@ stringset@~0.2.1: resolved "https://registry.yarnpkg.com/stringset/-/stringset-0.2.1.tgz#ef259c4e349344377fcd1c913dd2e848c9c042b5" integrity sha1-7yWcTjSTRDd/zRyRPdLoSMnAQrU= +strip-ansi@*, strip-ansi@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" + integrity sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw== + dependencies: + ansi-regex "^6.0.1" + strip-ansi@4.0.0, strip-ansi@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" @@ -39229,13 +39314,6 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" -strip-ansi@^7.0.0: - version "7.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2" - integrity sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw== - dependencies: - ansi-regex "^6.0.1" - strip-ansi@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.1.1.tgz#39e8a98d044d150660abe4a6808acf70bb7bc991" @@ -40001,7 +40079,7 @@ term-to-html@1.2.0: arg "4.1.3" escape-html "1.0.3" -terminal-banner@1.1.0: +terminal-banner@1.1.0, terminal-banner@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/terminal-banner/-/terminal-banner-1.1.0.tgz#ef81ce7d9d7e541a81d09eb2c0257c3d5463c3ea" integrity sha512-A70B8Io5gGOTKQuoqU6LUPLouNd9DvFLgw3cPh6bfrQjdy7HWW1t04VJfQwjTnygTVDX0xremaj1cg3SQaCGyg== @@ -43843,6 +43921,11 @@ workerpool@6.1.0: resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.1.0.tgz#a8e038b4c94569596852de7a8ea4228eefdeb37b" integrity sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg== +workerpool@6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.0.tgz#827d93c9ba23ee2019c3ffaff5c27fccea289e8b" + integrity sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A== + wrap-ansi@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" @@ -44178,7 +44261,7 @@ xtend@~3.0.0: resolved "https://registry.yarnpkg.com/xtend/-/xtend-3.0.0.tgz#5cce7407baf642cba7becda568111c493f59665a" integrity sha1-XM50B7r2Qsunvs2laBEcST9ZZlo= -xvfb-maybe@0.2.1: +xvfb-maybe@0.2.1, xvfb-maybe@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/xvfb-maybe/-/xvfb-maybe-0.2.1.tgz#ed8cb132957b7848b439984c66f010ea7f24361b" integrity sha1-7YyxMpV7eEi0OZhMZvAQ6n8kNhs=