diff --git a/.circleci/cache-version.txt b/.circleci/cache-version.txt index 5e88a75bc1a3..4a355f62e1a3 100644 --- a/.circleci/cache-version.txt +++ b/.circleci/cache-version.txt @@ -1,3 +1,3 @@ # Bump this version to force CI to re-create the cache from scratch. -9-13-22 +10-31-22 diff --git a/.circleci/config.yml b/.circleci/config.yml index 54357e7b979e..5696514e87ee 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -110,17 +110,19 @@ executors: environment: PLATFORM: windows - darwin-arm64: + darwin-arm64: &darwin-arm64-executor machine: true environment: PLATFORM: darwin - linux-arm64: + linux-arm64: &linux-arm64-executor machine: image: ubuntu-2004:2022.04.1 resource_class: arm.medium environment: PLATFORM: linux + # TODO: Disabling snapshots for now on Linux Arm 64 architectures. Will revisit with https://github.com/cypress-io/cypress/issues/23557 + DISABLE_SNAPSHOT_REQUIRE: 1 commands: verify_should_persist_artifacts: @@ -195,6 +197,11 @@ commands: command: | source ./scripts/ensure-node.sh yarn build + - run: + name: Generate v8 snapshot + command: | + source ./scripts/ensure-node.sh + yarn build-v8-snapshot-prod - prepare-modules-cache # So we don't throw these in the workspace cache - persist_to_workspace: root: ~/ @@ -474,7 +481,7 @@ commands: - run: name: Run driver tests in Cypress environment: - CYPRESS_KONFIG_ENV: production + CYPRESS_CONFIG_ENV: production command: | echo Current working directory is $PWD echo Total containers $CIRCLE_NODE_TOTAL @@ -558,7 +565,7 @@ commands: # internal PR cmd=$([[ <> == 'true' ]] && echo 'yarn percy exec --parallel -- --') || true DEBUG=<> \ - CYPRESS_KONFIG_ENV=production \ + CYPRESS_CONFIG_ENV=production \ CYPRESS_RECORD_KEY=$MAIN_RECORD_KEY \ PERCY_PARALLEL_NONCE=$CIRCLE_WORKFLOW_WORKSPACE_ID \ PERCY_ENABLE=${PERCY_TOKEN:-0} \ @@ -584,7 +591,7 @@ commands: cd ../.. DEBUG=<> \ - CYPRESS_KONFIG_ENV=production \ + CYPRESS_CONFIG_ENV=production \ PERCY_PARALLEL_NONCE=$CIRCLE_WORKFLOW_WORKSPACE_ID \ PERCY_ENABLE=${PERCY_TOKEN:-0} \ PERCY_PARALLEL_TOTAL=-1 \ @@ -1059,14 +1066,16 @@ commands: # notarization on Mac can take a while no_output_timeout: "45m" command: | + source ./scripts/ensure-node.sh + node --version if [[ `node ./scripts/get-platform-key.js` == 'linux-arm64' ]]; then # these are missing on Circle and there is no way to pre-install them on Arm sudo apt-get update sudo apt-get install -y libgtk2.0-0 libgtk-3-0 libgbm-dev libnotify-dev libgconf-2-4 libnss3 libxss1 libasound2 libxtst6 xauth xvfb + DISABLE_SNAPSHOT_REQUIRE=1 yarn binary-build --version $(node ./scripts/get-next-version.js) + else + yarn binary-build --version $(node ./scripts/get-next-version.js) fi - source ./scripts/ensure-node.sh - node --version - yarn binary-build --version $(node ./scripts/get-next-version.js) - run: name: Zip the binary command: | @@ -1203,7 +1212,7 @@ jobs: <<: *defaultsParameters resource_class: type: string - default: medium+ + default: large resource_class: << parameters.resource_class >> steps: - restore_cached_workspace @@ -1312,6 +1321,52 @@ jobs: PERCY_PARALLEL_TOTAL=-1 \ yarn percy snapshot ./cli/visual-snapshots + v8-integration-tests: + <<: *defaults + parameters: + <<: *defaultsParameters + resource_class: + type: string + default: medium + resource_class: << parameters.resource_class >> + parallelism: 1 + steps: + - restore_cached_workspace + - restore_cached_system_tests_deps + # TODO: Remove this once we switch off self-hosted M1 runners + - when: + condition: + equal: [ *darwin-arm64-executor, << parameters.executor >> ] + steps: + - run: rm -f /tmp/cypress/junit/* + - unless: + condition: + or: + - equal: [ *linux-arm64-executor, << parameters.executor >> ] # TODO: Figure out how to support linux-arm64 when we get to linux arm64 build: https://github.com/cypress-io/cypress/issues/23557 + steps: + - run: + name: Run v8 integration tests + command: | + source ./scripts/ensure-node.sh + yarn test-integration --scope "'@tooling/{packherd,v8-snapshot,electron-mksnapshot}'" + - verify-mocha-results: + expectedResultCount: 3 + - when: + condition: + or: + - equal: [ *linux-arm64-executor, << parameters.executor >> ] + steps: + - run: + name: Run v8 integration tests + command: | + source ./scripts/ensure-node.sh + yarn test-integration --scope "'@tooling/packherd'" + - verify-mocha-results: + expectedResultCount: 1 + - store_test_results: + path: /tmp/cypress + - store-npm-logs + unit-tests: <<: *defaults parameters: @@ -1342,7 +1397,7 @@ jobs: # run type checking for each individual package - run: yarn lerna run types - verify-mocha-results: - expectedResultCount: 10 + expectedResultCount: 18 - store_test_results: path: /tmp/cypress # CLI tests generate HTML files with sample CLI command output @@ -1673,7 +1728,7 @@ jobs: working_directory: packages/reporter - run: command: | - CYPRESS_KONFIG_ENV=production \ + CYPRESS_CONFIG_ENV=production \ CYPRESS_RECORD_KEY=$MAIN_RECORD_KEY \ PERCY_PARALLEL_NONCE=$CIRCLE_WORKFLOW_WORKSPACE_ID \ PERCY_ENABLE=${PERCY_TOKEN:-0} \ @@ -1696,7 +1751,7 @@ jobs: - restore_cached_system_tests_deps - run: command: | - CYPRESS_KONFIG_ENV=production \ + CYPRESS_CONFIG_ENV=production \ CYPRESS_RECORD_KEY=$MAIN_RECORD_KEY \ PERCY_PARALLEL_NONCE=$CIRCLE_WORKFLOW_WORKSPACE_ID \ PERCY_ENABLE=${PERCY_TOKEN:-0} \ @@ -1718,7 +1773,7 @@ jobs: - restore_cached_system_tests_deps - run: command: | - CYPRESS_KONFIG_ENV=production \ + CYPRESS_CONFIG_ENV=production \ CYPRESS_RECORD_KEY=$MAIN_RECORD_KEY \ PERCY_PARALLEL_NONCE=$CIRCLE_WORKFLOW_WORKSPACE_ID \ PERCY_ENABLE=${PERCY_TOKEN:-0} \ @@ -1853,7 +1908,7 @@ jobs: name: Build command: yarn workspace @cypress/mount-utils build - store-npm-logs - + npm-xpath: <<: *defaults resource_class: small @@ -1928,7 +1983,7 @@ jobs: <<: *defaultsParameters resource_class: type: string - default: medium+ + default: large resource_class: << parameters.resource_class >> steps: - restore_cached_workspace @@ -1947,6 +2002,7 @@ jobs: type: string default: medium+ steps: + - restore_cached_workspace - clone-repo-and-checkout-branch: repo: cypress-example-kitchensink - install-required-node @@ -1982,6 +2038,7 @@ jobs: test-kitchensink-against-staging: <<: *defaults steps: + - restore_cached_workspace - clone-repo-and-checkout-branch: repo: cypress-example-kitchensink - install-required-node @@ -2007,6 +2064,7 @@ jobs: test-against-staging: <<: *defaults steps: + - restore_cached_workspace - clone-repo-and-checkout-branch: repo: cypress-test-tiny - run: @@ -2434,11 +2492,10 @@ linux-x64-workflow: &linux-x64-workflow context: test-runner:cypress-record-key requires: - build - # TODO: Implement WebKit network automation to fix the majority of these tests before re-enabling - # - driver-integration-tests-webkit-experimentalSessionAndOrigin: - # context: test-runner:cypress-record-key - # requires: - # - build + - driver-integration-tests-webkit-experimentalSessionAndOrigin: + context: test-runner:cypress-record-key + requires: + - build - run-frontend-shared-component-tests-chrome: context: [test-runner:cypress-record-key, test-runner:launchpad-tests, test-runner:percy] percy: true @@ -2514,6 +2571,9 @@ linux-x64-workflow: &linux-x64-workflow - npm-cypress-schematic: requires: - build + - v8-integration-tests: + requires: + - system-tests-node-modules-install # This release definition must be updated with any new jobs # Any attempts to automate this are welcome # If CircleCI provided an "after all" hook, then this wouldn't be necessary @@ -2564,6 +2624,7 @@ linux-x64-workflow: &linux-x64-workflow - run-reporter-component-tests-chrome - run-webpack-dev-server-integration-tests - run-vite-dev-server-integration-tests + - v8-integration-tests # various testing scenarios, like building full binary # and testing it on a real project @@ -2674,6 +2735,13 @@ linux-arm64-workflow: &linux-arm64-workflow requires: - linux-arm64-build + - v8-integration-tests: + name: linux-arm64-v8-integration-tests + executor: linux-arm64 + resource_class: arm.medium + requires: + - linux-arm64-build + darwin-x64-workflow: &darwin-x64-workflow jobs: - node_modules_install: @@ -2713,6 +2781,13 @@ darwin-x64-workflow: &darwin-x64-workflow requires: - darwin-x64-build + - v8-integration-tests: + name: darwin-x64-v8-integration-tests + executor: mac + resource_class: macos.x86.medium.gen2 + requires: + - darwin-x64-build + darwin-arm64-workflow: &darwin-arm64-workflow jobs: - node_modules_install: @@ -2739,6 +2814,13 @@ darwin-arm64-workflow: &darwin-arm64-workflow requires: - darwin-arm64-build + - v8-integration-tests: + name: darwin-arm64-v8-integration-tests + executor: darwin-arm64 + resource_class: cypress-io/latest_m1 + requires: + - darwin-arm64-build + windows-workflow: &windows-workflow jobs: - node_modules_install: @@ -2800,6 +2882,13 @@ windows-workflow: &windows-workflow requires: - windows-create-build-artifacts + - v8-integration-tests: + name: windows-v8-integration-tests + executor: windows + resource_class: windows.large + requires: + - windows-build + workflows: linux-x64: <<: *linux-x64-workflow diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 67d09054c492..000000000000 --- a/.eslintignore +++ /dev/null @@ -1,115 +0,0 @@ -# unignore hidden files -!.* - -**/__snapshots__ -**/_test-output -**/build -**/cypress/fixtures -**/dist -**/dist-* -**/node_modules -**/support/fixtures/* -!**/support/fixtures/projects -**/support/fixtures/projects/**/_fixtures/* -**/support/fixtures/projects/**/static/* -**/support/fixtures/projects/**/*.jsx -**/support/fixtures/projects/**/fail.js - -system-tests/fixtures/* -!system-tests/projects -system-tests/projects/**/_fixtures/* -system-tests/projects/**/static/* -system-tests/projects/**/*.jsx -system-tests/projects/**/fail.js -system-tests/lib/scaffold/plugins/index.js -system-tests/lib/scaffold/support/e2e.js -system-tests/lib/scaffold/support/component.js -system-tests/lib/scaffold/support/commands.js -system-tests/test/support/projects/e2e/cypress/ -system-tests/projects/e2e/cypress/e2e/stdout_exit_early_failing.cy.js -system-tests/projects/e2e/cypress/e2e/typescript_syntax_error.cy.ts -system-tests/projects/config-with-ts-syntax-error/** -system-tests/projects/config-with-ts-module-error/** -system-tests/projects/no-specs-vue-2/** - - -**/test/fixtures -**/vendor - -# cli/types is linted by tslint/dtslint -cli/types - -# cli/react, cli/vue, and cli/mount-utils are all copied from dist'd builds -cli/react -cli/vue -cli/vue2 -cli/mount-utils - -# packages/example is not linted (think about changing this) -packages/example - -packages/extension/test/helpers/background.js -e2e/stdout_exit_early_failing_spec.js - -npm/webpack-preprocessor/cypress/tests/e2e/compile-error.js -npm/webpack-preprocessor/examples/use-babelrc/cypress/e2e/spec.cy.js - -npm/cypress-schematic/src/**/*.js - -**/.projects -**/*.d.ts -**/package-lock.json -**/tsconfig.json -**/.vscode -**/.history -**/.cy -**/.git - -/npm/react/bin/* -/npm/react/**/coverage -**/.next/** -/npm/create-cypress-tests/initial-template -/npm/create-cypress-tests/**/*.template.* - -# The global eslint configuration is not set up to parse vue@2 files -/npm/vue2/**/*.vue - -npm/grep/cypress - -packages/data-context/test/unit/codegen/files -packages/config/test/__fixtures__/**/* -packages/config/test/__babel_fixtures__/**/* - -# community templates we test against, no need to lint -system-tests/projects/cra-4/**/* -system-tests/projects/cra-5/**/* -system-tests/projects/cra-ejected/**/* -system-tests/projects/create-react-app-configured/**/* -system-tests/projects/create-react-app-unconfigured/**/* -system-tests/projects/create-react-app-custom-index-html - -system-tests/projects/vueclivue2-unconfigured/**/* -system-tests/projects/vueclivue2-configured/**/* -system-tests/projects/outdated-deps-vuecli3/**/* - -system-tests/projects/vueclivue3-unconfigured/**/* -system-tests/projects/vueclivue3-configured/**/* -system-tests/projects/vueclivue3-custom-index-html - -system-tests/projects/vuecli5vue3-unconfigured/**/* -system-tests/projects/vuecli5vue3-configured/**/* - -system-tests/projects/vue3-vite-ts-unconfigured/**/* -system-tests/projects/vue3-vite-ts-configured/**/* -system-tests/projects/vue3-vite-ts-custom-index-html - -system-tests/projects/nextjs-unconfigured/**/* -system-tests/projects/nextjs-configured/**/* - -system-tests/projects/nuxtjs-vue2-unconfigured/**/* -system-tests/projects/nuxtjs-vue2-configured/**/* - -system-tests/projects/react-app-webpack-5-unconfigured/**/* - -system-tests/project-fixtures/** -system-tests/projects/**/*/expected-cypress*/**/* diff --git a/.eslintrc.js b/.eslintrc.js index 7abb027d019b..a5e6e3ba3e40 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -41,6 +41,7 @@ module.exports = { '**/scripts/**', '**/test/**', '**/system-tests/**', + 'tooling/**', 'packages/{app,driver,frontend-shared,launchpad}/cypress/**', '*.test.ts', // ignore in packages that don't run in the Cypress process diff --git a/.github/ISSUE_TEMPLATE/4-flaky-test.yml b/.github/ISSUE_TEMPLATE/4-flaky-test.yml index abcc4baa9553..cb30750bcb98 100644 --- a/.github/ISSUE_TEMPLATE/4-flaky-test.yml +++ b/.github/ISSUE_TEMPLATE/4-flaky-test.yml @@ -10,8 +10,8 @@ body: - type: textarea id: dashboard attributes: - label: Link to dashboard or CircleCI failure - description: Please include a link to the failure in the Cypress Dashboard or in CircleCI. + label: Link to Cypress Cloud or CircleCI failure + description: Please include a link to the failure in Cypress Cloud or in CircleCI. validations: required: true - type: textarea diff --git a/.gitignore b/.gitignore index c496b2a02dc0..ce0f3b177ba0 100644 --- a/.gitignore +++ b/.gitignore @@ -117,6 +117,9 @@ cli/visual-snapshots # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 +# Fleet +.fleet/ + # User-specific stuff .idea .idea/**/workspace.xml @@ -382,3 +385,7 @@ globbed_node_modules # Autogenerated files, typically from graphql-code-generator *.gen.ts *.gen.json + +# Snapshot Binaries +snapshot_blob.bin +v8_context_snapshot.x86_64.bin diff --git a/.vscode/cspell.json b/.vscode/cspell.json index 5649488074b9..e6f43e8131aa 100644 --- a/.vscode/cspell.json +++ b/.vscode/cspell.json @@ -8,6 +8,7 @@ "composables", "dedup", "ERRORED", + "esbuild", "execa", "Fetchable", "Fetchables", @@ -19,10 +20,13 @@ "intlify", "Lachlan", "loggedin", + "mksnapshot", "msapplication", + "norewrite", "NOTESTS", "OVERLIMIT", "overscan", + "packherd", "Pinia", "pnpm", "pseudoclass", @@ -30,6 +34,12 @@ "Screenshotting", "semibold", "shiki", + "snapbuild", + "snapgen", + "snapshottable", + "snapshotted", + "snapshotting", + "sourcemaps", "speclist", "testid", "TIMEDOUT", @@ -37,6 +47,7 @@ "topnav", "unconfigured", "unplugin", + "unref", "unrunnable", "unstaged", "urql", @@ -48,4 +59,4 @@ ], "ignoreWords": [], "import": [] -} \ No newline at end of file +} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 57460ad0810b..8b15d616c664 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -128,18 +128,19 @@ Cypress is a large open source project. When you want to contribute to Cypress, Cypress uses a monorepo, which means there are many independent packages in this repository. There are two main types of packages: private and public. -Private packages generally live within the [`packages`](./packages) directory and are in the `@packages/` namespace. These packages are combined to form the main Cypress app that you get when you `npm install cypress`. They are discrete modules with different responsibilities, but each is necessary for the Cypress app and is not necessarily useful outside of the Cypress app. Since these modules are all compiled and bundled into a binary upon release, they are sometimes collectively referred to as the Cypress binary. +Private packages included in the app generally live within the [`packages`](./packages) directory and are in the `@packages/` namespace. These packages are combined to form the main Cypress app that you get when you `npm install cypress`. They are discrete modules with different responsibilities, but each is necessary for the Cypress app and is not necessarily useful outside of the Cypress app. Since these modules are all compiled and bundled into a binary upon release, they are sometimes collectively referred to as the Cypress binary. Here is a list of the core packages in this repository with a short description, located within the [`packages`](./packages) directory: | Folder Name | Package Name | Purpose | | :------------------------------------ | :---------------------- | :--------------------------------------------------------------------------- | | [cli](./cli) | `cypress` | The command-line tool that is packaged as an `npm` module. | - | [app](./packages/app) | `@packages/app` | The the front-end for the Cypress App that renders in the launched browser instance. | + | [app](./packages/app) | `@packages/app` | The front-end for the Cypress App that renders in the launched browser instance. | | [config](./packages/config) | `@packages/config` | The Cypress configuration types and validation used in the server, data-context and driver. | | [data-context](./packages/data-context) | `@packages/data-context` | Centralized data access for the Cypress application. | | [driver](./packages/driver) | `@packages/driver` | The code that is used to drive the behavior of the API commands. | | [electron](./packages/electron) | `@packages/electron` | The Cypress implementation of Electron. | + | [errors](./packages/errors) | `@packages/errors` | Error definitions and utilities for Cypress | | [example](./packages/example) | `@packages/example` | Our example kitchen-sink application. | | [extension](./packages/extension) | `@packages/extension` | The Cypress Chrome browser extension | | [frontend-shared](./packages/frontend-shared) | `@packages/frontend-shared` | Shared components and styles used in the `app` and `launchpad`. | @@ -150,6 +151,7 @@ Here is a list of the core packages in this repository with a short description, | [launchpad](./packages/launchpad) | `@packages/launcher` | The portal to running Cypress that displays in `open` mode. | | [net-stubbing](./packages/net-stubbing) | `@packages/net-stubbing` | Contains server side code for Cypress' network stubbing features. | | [network](./packages/network) | `@packages/network` | Various utilities related to networking. | + | [packherd-require](./packages/packherd-require) | `@packages/packherd-require` | Loads modules that have been bundled by `@tooling/packherd`. | | [proxy](./packages/proxy) | `@packages/proxy` | Code for Cypress' network proxy layer. | | [reporter](./packages/reporter) | `@packages/reporter` | The reporter shows the running results of the tests (The Command Log UI). | | [resolve-dist](./packages/resolve-dist) | `@packages/resolve-dist` | Centralizes the resolution of paths to compiled/static assets from server-side code.. | @@ -161,8 +163,19 @@ Here is a list of the core packages in this repository with a short description, | [socket](./packages/socket) | `@packages/socket` | A wrapper around socket.io to provide common libraries. | | [ts](./packages/ts) | `@packages/ts` | A centralized version of typescript. | | [types](./packages/types) | `@packages/types` | The shared internal Cypress types. | + | [v8-snapshot-require](./packages/v8-snapshot-require) | `@packages/v8-snapshot-requie` | Tool to load a snapshot for Electron applications that was created by `@tooling/v8-snapshot`. | | [web-config](./packages/web-config) | `@packages/ui-components` | The web-related configuration. | +Private packages involved in development of the app live within the [`tooling`](./tooling) directory and are in the `@tooling/` namespace. They are discrete modules with different responsibilities, but each is necessary for development of the Cypress app and is not necessarily useful outside of the Cypress app. + +Here is a list of the packages in this repository with a short description, located within the [`tooling`](./tooling) directory: + + | Folder Name | Package Name | Purpose | + | :------------------------------------ | :---------------------- | :--------------------------------------------------------------------------- | + | [electron-mksnapshot](./electron-mksnapshot) | `electron-mksnapshot` | A rewrite of [electron/mksnapshot](https://github.com/electron/mksnapshot) to support multiple versions. | + | [packherd](./tooling/packherd) | `packherd` | Herds all dependencies reachable from an entry and packs them. | + | [v8-snapshot](./tooling/v8-snapshot) | `v8-snapshot` | Tool to create a snapshot for Electron applications. | + Public packages live within the [`npm`](./npm) folder and are standalone modules that get independently published to npm under the `@cypress/` namespace. These packages generally contain extensions, plugins, or other packages that are complementary to, yet independent of, the main Cypress app. Here is a list of the npm packages in this repository: @@ -172,9 +185,11 @@ Here is a list of the npm packages in this repository: | [angular](./npm/angular) | `@cypress/angular` | Cypress component testing for Angular. | | [create-cypress-tests](./npm/create-cypress-tests) | `@cypress/create-cypress-tests` | Tooling to scaffold Cypress configuration and demo test files. | | [eslint-plugin-dev](./npm/eslint-plugin-dev) | `@cypress/eslint-plugin-dev` | Eslint plugin for internal development. | + | [grep](./npm/grep) | `@cypress/grep` | Filter tests using substring | | [mount-utils](./npm/mount-utils) | `@cypress/mount-utils` | Common functionality for Vue/React/Angular adapters. | | [react](./npm/react) | `@cypress/react` | Cypress component testing for React. | | [react18](./npm/react18) | `@cypress/react18` | Cypress component testing for React 18. | + | [schematic](./npm/cypress-schematic) | `@cypress/schematic` | Official Angular Schematic and Builder for the Angular CLI.| | [svelte](./npm/svelte) | `@cypress/svelte` | Cypress component testing for Svelte. | | [vite-dev-server](./npm/vite-dev-server) | `@cypress/vite-dev-server` | Vite powered dev server for Component Testing. | | [vue](./npm/vue) | `@cypress/vue` | Cypress component testing for Vue 3. | @@ -182,7 +197,7 @@ Here is a list of the npm packages in this repository: | [webpack-batteries-included-preprocessor](./npm/webpack-batteries-included-preprocessor) | `@cypress/webpack-batteries-included-preprocessor` | Cypress preprocessor for bundling JavaScript via webpack with dependencies included and support for various ES features, TypeScript, and CoffeeScript. | | [webpack-dev-server](./npm/webpack-dev-server) | `@cypress/webpack-dev-server` | Webpack powered dev server for Component Testing. | | [webpack-preprocessor](./npm/webpack-preprocessor) | `@cypress/webpack-preprocessor` | Cypress preprocessor for bundling JavaScript via webpack. | - | [xpath](./npm/xpath) | `@cypress/xpath` | Adds XPath command to Cypress.io test runner. | + | [xpath](./npm/xpath) | `@cypress/xpath` | Adds XPath command to Cypress.io test runner | We try to tag all issues with a `pkg/` or `npm/` tag describing the appropriate package the work is required in. For public packages, we use their qualified package name: For example, issues relating to the webpack preprocessor are tagged under [`npm: @cypress/webpack-preprocessor`](https://github.com/cypress-io/cypress/labels/npm%3A%20%40cypress%2Fwebpack-preprocessor) label and issues related to the `driver` package are tagged with the [`pkg/driver`](https://github.com/cypress-io/cypress/labels/pkg%2Fdriver) label. @@ -223,7 +238,7 @@ If there are errors building the packages, prefix the commands with `DEBUG=cypre When running `yarn start` this routes through the CLI and eventually calls `yarn dev` with the proper arguments. This enables Cypress day-to-day development to match the logic of the built binary + CLI integration. -If you want to bypass the CLI entirely, you can use the `yarn dev` task and pass arguments directly. For example, to headlessly run a project in a given folder, while trying to record to the Dashboard +If you want to bypass the CLI entirely, you can use the `yarn dev` task and pass arguments directly. For example, to headlessly run a project in a given folder, while trying to record to Cypress Cloud. ```text yarn dev --run-project /project/folder --record --key @@ -394,6 +409,67 @@ Each package documents how to best work with it, so consult the `README.md` of e They will outline development and test procedures. When in doubt just look at the `scripts` of each `package.json` file. Everything we do at Cypress is contained there. +### V8 Snapshotting + +In order to improve start up time, Cypress uses [electron mksnapshot](https://github.com/electron/mksnapshot) for generating [v8 snapshots](https://v8.dev/blog/custom-startup-snapshots) for both development and production. + +#### Snapshot Generation + +Locally, a v8 snapshot is generated in a post install step and set up to only include node modules. In this way, cypress code can be modified without having to regenerate a snapshot. If you do want or need to regenerate the snapshot for development you can run: + +``` +yarn build-v8-snapshot-dev +``` + +On CI and for binary builds we run: + +``` +yarn build-v8-snapshot-prod +``` + +which will include both node modules and cypress code. + +During the process of snapshot generation, metadata is created/updated in `tooling/v8-snapshot/cache`. Changes to these files can and should be committed to the repo as it will make subsequent snapshot generations faster. + +#### Troubleshooting + +**Generation** + +If you run into errors while generating the v8 snapshot, you can occasionally identify the problem dependency via the output. You can try to remove that dependency from the cache and see if regenerating succeeds. If it does, likely it was moved to a more restrictive section (e.g. healthy to deferred/no-rewrite or deferred to norewrite). If all else fails, you can try running the following (but keep in mind this may take a while): + +``` +V8_SNAPSHOT_FROM_SCRATCH=1 yarn build-v8-snapshot-dev +``` + +or + +``` +V8_SNAPSHOT_FROM_SCRATCH=1 yarn build-v8-snapshot-prod +``` + +**Runtime** + +If you're experiencing issues during runtime, you can try and narrow down where the problem might be via a few different scenarios: + +* If the problem occurs with the binary, but not in the monorepo, chances are something is being removed during the binary cleanup step that shouldn't be +* If the problem occurs with running `yarn build-v8-snapshot-prod` but not `yarn build-v8-snapshot-dev`, then that means there's a problem with a cypress file and not a node module dependency. Chances are that a file is not being flagged properly (e.g. healthy when it should be deferred or norewrite). +* If the problem occurs with both `yarn build-v8-snapshot-prod` and `yarn build-v8-snapshot-dev` but does not occur when using the `DISABLE_SNAPSHOT_REQUIRE` environment variable, then that means there's a problem with a node module dependency. Chances are that a file is not being flagged properly (e.g. healthy when it should be deferred or norewrite). +* If the problem still occurs when using the `DISABLE_SNAPSHOT_REQUIRE` environment variable, then that means the problem is not snapshot related. + +**Build Length** + +If the `build-v8-snapshot-prod` command is taking a long time to run on Circle CI, the snapshot cache probably needs to be updated. Run these commands on a windows, linux, and mac and commit the updates to the snapshot cache to git: + +``` +yarn build-v8-snapshot-dev +``` + +or + +``` +yarn build-v8-snapshot-prod +``` + ## Committing Code ### Branches diff --git a/cli/.eslintignore b/cli/.eslintignore new file mode 100644 index 000000000000..a3f72532311c --- /dev/null +++ b/cli/.eslintignore @@ -0,0 +1,14 @@ +**/__snapshots__ +/build + +# cli/types is linted by tslint/dtslint +/types + +# these are all copied from dist'd builds from the individual libs +/angular +/react +/react18 +/vue +/vue2 +/svelte +/mount-utils \ No newline at end of file diff --git a/cli/__snapshots__/build_spec.js b/cli/__snapshots__/build_spec.js index 4be1b245a7e9..751f417d0e3a 100644 --- a/cli/__snapshots__/build_spec.js +++ b/cli/__snapshots__/build_spec.js @@ -1,36 +1,37 @@ exports['package.json build outputs expected properties 1'] = { - "name": "test", - "engines": "test engines", - "version": "x.y.z", - "buildInfo": "replaced by normalizePackageJson", - "description": "Cypress.io end to end testing tool", - "homepage": "https://github.com/cypress-io/cypress", - "license": "MIT", - "bugs": { - "url": "https://github.com/cypress-io/cypress/issues" + 'name': 'test', + 'engines': 'test engines', + 'version': 'x.y.z', + 'buildInfo': 'replaced by normalizePackageJson', + 'description': 'Cypress is a next generation front end testing tool built for the modern web', + 'homepage': 'https://github.com/cypress-io/cypress', + 'license': 'MIT', + 'bugs': { + 'url': 'https://github.com/cypress-io/cypress/issues', }, - "repository": { - "type": "git", - "url": "https://github.com/cypress-io/cypress.git" + 'repository': { + 'type': 'git', + 'url': 'https://github.com/cypress-io/cypress.git', }, - "keywords": [ - "automation", - "browser", - "cypress", - "cypress.io", - "e2e", - "end-to-end", - "integration", - "mocks", - "runner", - "spies", - "stubs", - "test", - "testing" + 'keywords': [ + 'automation', + 'browser', + 'cypress', + 'cypress.io', + 'e2e', + 'end-to-end', + 'integration', + 'component', + 'mocks', + 'runner', + 'spies', + 'stubs', + 'test', + 'testing', ], - "types": "types", - "scripts": { - "postinstall": "node index.js --exec install", - "size": "t=\"$(npm pack .)\"; wc -c \"${t}\"; tar tvf \"${t}\"; rm \"${t}\";" - } + 'types': 'types', + 'scripts': { + 'postinstall': 'node index.js --exec install', + 'size': 't="$(npm pack .)"; wc -c "${t}"; tar tvf "${t}"; rm "${t}";', + }, } diff --git a/cli/__snapshots__/cli_spec.js b/cli/__snapshots__/cli_spec.js index 0e15c004957e..69137521fbac 100644 --- a/cli/__snapshots__/cli_spec.js +++ b/cli/__snapshots__/cli_spec.js @@ -74,7 +74,7 @@ exports['shows help for run --foo 1'] = ` -C, --config-file path to script file where configuration values are set. defaults to "cypress.config.{js,ts,mjs,cjs}". --e2e runs end to end tests -e, --env sets environment variables. separate multiple values with a comma. overrides any value in cypress.config.{js,ts,mjs,cjs} or cypress.env.json - --group a named group for recorded runs in the Cypress Dashboard + --group a named group for recorded runs in Cypress Cloud -k, --key your secret Record Key. you can omit this if you set a CYPRESS_RECORD_KEY environment variable. --headed displays the browser instead of running headlessly --headless hide the browser instead of running headed (default for cypress run) @@ -83,11 +83,11 @@ exports['shows help for run --foo 1'] = ` -p, --port runs Cypress on a specific port. overrides any value in cypress.config.{js,ts,mjs,cjs}. -P, --project path to the project -q, --quiet run quietly, using only the configured reporter - --record [bool] records the run. sends test results, screenshots and videos to your Cypress Dashboard. + --record [bool] records the run. sends test results, screenshots and videos to Cypress Cloud. -r, --reporter runs a specific mocha reporter. pass a path to use a custom reporter. defaults to "spec" -o, --reporter-options options for the mocha reporter. defaults to "null" -s, --spec runs specific spec file(s). defaults to "all" - -t, --tag named tag(s) for recorded runs in the Cypress Dashboard + -t, --tag named tag(s) for recorded runs in Cypress Cloud --dev runs cypress in development and bypasses binary check -h, --help display help for command ------- diff --git a/cli/__snapshots__/cypress_spec.js b/cli/__snapshots__/cypress_spec.js index 875a36c441b7..f603cfb784e9 100644 --- a/cli/__snapshots__/cypress_spec.js +++ b/cli/__snapshots__/cypress_spec.js @@ -1,4 +1,4 @@ exports['cypress .run resolves with contents of tmp file 1'] = { - "code": 0, - "failingTests": [] + 'code': 0, + 'failingTests': [], } diff --git a/cli/__snapshots__/errors_spec.js b/cli/__snapshots__/errors_spec.js index 0b0fdd013540..05e1ce7edcb9 100644 --- a/cli/__snapshots__/errors_spec.js +++ b/cli/__snapshots__/errors_spec.js @@ -50,8 +50,8 @@ Cypress Version: 1.2.3 ` exports['child kill error object'] = { - "description": "The Test Runner unexpectedly exited via a exit event with signal SIGKILL", - "solution": "Please search Cypress documentation for possible solutions:\n\n https://on.cypress.io\n\nCheck if there is a GitHub issue describing this crash:\n\n https://github.com/cypress-io/cypress/issues\n\nConsider opening a new issue." + 'description': 'The Test Runner unexpectedly exited via a exit event with signal SIGKILL', + 'solution': 'Please search Cypress documentation for possible solutions:\n\n https://on.cypress.io\n\nCheck if there is a GitHub issue describing this crash:\n\n https://github.com/cypress-io/cypress/issues\n\nConsider opening a new issue.', } exports['Error message'] = ` @@ -74,29 +74,29 @@ Cypress Version: 1.2.3 ` exports['errors individual has the following errors 1'] = [ - "CYPRESS_RUN_BINARY", - "binaryNotExecutable", - "childProcessKilled", - "failedDownload", - "failedUnzip", - "failedUnzipWindowsMaxPathLength", - "incompatibleHeadlessFlags", - "incompatibleTestTypeFlags", - "incompatibleTestingTypeAndFlag", - "invalidCacheDirectory", - "invalidConfigFile", - "invalidCypressEnv", - "invalidOS", - "invalidRunProjectPath", - "invalidSmokeTestDisplayError", - "invalidTestingType", - "missingApp", - "missingDependency", - "missingXvfb", - "nonZeroExitCodeXvfb", - "notInstalledCI", - "smokeTestFailure", - "unexpected", - "unknownError", - "versionMismatch" + 'CYPRESS_RUN_BINARY', + 'binaryNotExecutable', + 'childProcessKilled', + 'failedDownload', + 'failedUnzip', + 'failedUnzipWindowsMaxPathLength', + 'incompatibleHeadlessFlags', + 'incompatibleTestTypeFlags', + 'incompatibleTestingTypeAndFlag', + 'invalidCacheDirectory', + 'invalidConfigFile', + 'invalidCypressEnv', + 'invalidOS', + 'invalidRunProjectPath', + 'invalidSmokeTestDisplayError', + 'invalidTestingType', + 'missingApp', + 'missingDependency', + 'missingXvfb', + 'nonZeroExitCodeXvfb', + 'notInstalledCI', + 'smokeTestFailure', + 'unexpected', + 'unknownError', + 'versionMismatch', ] diff --git a/cli/__snapshots__/run_spec.js b/cli/__snapshots__/run_spec.js index 1d9b1bb4bf72..49d3ba1b8ef0 100644 --- a/cli/__snapshots__/run_spec.js +++ b/cli/__snapshots__/run_spec.js @@ -1,27 +1,27 @@ exports['exec run .processRunOptions does not remove --record option when using --browser 1'] = [ - "--run-project", + '--run-project', null, - "--browser", - "test browser", - "--record", - "foo" + '--browser', + 'test browser', + '--record', + 'foo', ] exports['exec run .processRunOptions passes --browser option 1'] = [ - "--run-project", + '--run-project', null, - "--browser", - "test browser" + '--browser', + 'test browser', ] exports['exec run .processRunOptions passes --record option 1'] = [ - "--run-project", + '--run-project', null, - "--record", - "my record id" + '--record', + 'my record id', ] exports['exec run .processRunOptions defaults to e2e testingType 1'] = [ - "--run-project", - null + '--run-project', + null, ] diff --git a/cli/__snapshots__/spawn_spec.js b/cli/__snapshots__/spawn_spec.js index 797395f38fdc..9af35625fca4 100644 --- a/cli/__snapshots__/spawn_spec.js +++ b/cli/__snapshots__/spawn_spec.js @@ -1,18 +1,18 @@ exports['lib/exec/spawn .start forces colors and streams when supported 1'] = { - "FORCE_COLOR": "1", - "DEBUG_COLORS": "1", - "MOCHA_COLORS": "1", - "FORCE_STDIN_TTY": "1", - "FORCE_STDOUT_TTY": "1", - "FORCE_STDERR_TTY": "1" + 'FORCE_COLOR': '1', + 'DEBUG_COLORS': '1', + 'MOCHA_COLORS': '1', + 'FORCE_STDIN_TTY': '1', + 'FORCE_STDOUT_TTY': '1', + 'FORCE_STDERR_TTY': '1', } exports['lib/exec/spawn .start does not force colors and streams when not supported 1'] = { - "FORCE_COLOR": "0", - "DEBUG_COLORS": "0", - "FORCE_STDIN_TTY": "0", - "FORCE_STDOUT_TTY": "0", - "FORCE_STDERR_TTY": "0" + 'FORCE_COLOR': '0', + 'DEBUG_COLORS': '0', + 'FORCE_STDIN_TTY': '0', + 'FORCE_STDOUT_TTY': '0', + 'FORCE_STDERR_TTY': '0', } exports['lib/exec/spawn .start detects kill signal exits with error on SIGKILL 1'] = ` diff --git a/cli/__snapshots__/util_spec.js b/cli/__snapshots__/util_spec.js index 525f9bf06c8c..c65580b8953b 100644 --- a/cli/__snapshots__/util_spec.js +++ b/cli/__snapshots__/util_spec.js @@ -1,27 +1,27 @@ exports['config_as_object 1'] = { - "config": "{\"baseUrl\":\"http://localhost:2000\",\"watchForFileChanges\":false}" + 'config': '{"baseUrl":"http://localhost:2000","watchForFileChanges":false}', } exports['env_as_object 1'] = { - "env": "{\"foo\":\"bar\",\"magicNumber\":1234,\"host\":\"kevin.dev.local\"}" + 'env': '{"foo":"bar","magicNumber":1234,"host":"kevin.dev.local"}', } exports['env_as_string 1'] = { - "env": "foo=bar" + 'env': 'foo=bar', } exports['others_unchanged 1'] = { - "foo": "bar" + 'foo': 'bar', } exports['reporter_options_as_object 1'] = { - "reporterOptions": "{\"mochaFile\":\"results/my-test-output.xml\",\"toConsole\":true}" + 'reporterOptions': '{"mochaFile":"results/my-test-output.xml","toConsole":true}', } exports['spec_as_array 1'] = { - "spec": "[\"a\",\"b\",\"c\"]" + 'spec': '["a","b","c"]', } exports['spec_as_string 1'] = { - "spec": "x,y,z" + 'spec': 'x,y,z', } diff --git a/cli/lib/cli.js b/cli/lib/cli.js index 052893ca4c99..ce34a1b696f3 100644 --- a/cli/lib/cli.js +++ b/cli/lib/cli.js @@ -110,7 +110,7 @@ const descriptions = { exit: 'keep the browser open after tests finish', forceInstall: 'force install the Cypress binary', global: 'force Cypress into global mode as if its globally installed', - group: 'a named group for recorded runs in the Cypress Dashboard', + group: 'a named group for recorded runs in Cypress Cloud', headed: 'displays the browser instead of running headlessly', headless: 'hide the browser instead of running headed (default for cypress run)', key: 'your secret Record Key. you can omit this if you set a CYPRESS_RECORD_KEY environment variable.', @@ -118,11 +118,11 @@ const descriptions = { port: 'runs Cypress on a specific port. overrides any value in cypress.config.{js,ts,mjs,cjs}.', project: 'path to the project', quiet: 'run quietly, using only the configured reporter', - record: 'records the run. sends test results, screenshots and videos to your Cypress Dashboard.', + record: 'records the run. sends test results, screenshots and videos to Cypress Cloud.', reporter: 'runs a specific mocha reporter. pass a path to use a custom reporter. defaults to "spec"', reporterOptions: 'options for the mocha reporter. defaults to "null"', spec: 'runs specific spec file(s). defaults to "all"', - tag: 'named tag(s) for recorded runs in the Cypress Dashboard', + tag: 'named tag(s) for recorded runs in Cypress Cloud', version: 'prints Cypress version', } @@ -405,7 +405,21 @@ module.exports = { args = process.argv } - const { CYPRESS_INTERNAL_ENV } = process.env + const { CYPRESS_INTERNAL_ENV, CYPRESS_DOWNLOAD_USE_CA } = process.env + + if (process.env.CYPRESS_DOWNLOAD_USE_CA) { + let msg = ` + ${logSymbols.warning} Warning: It looks like you're setting CYPRESS_DOWNLOAD_USE_CA=${CYPRESS_DOWNLOAD_USE_CA} + + The environment variable "CYPRESS_DOWNLOAD_USE_CA" is no longer required to be set. + + You can safely unset this environment variable. + ` + + logger.log() + logger.warn(stripIndent(msg)) + logger.log() + } if (!util.isValidCypressInternalEnvValue(CYPRESS_INTERNAL_ENV)) { debug('invalid CYPRESS_INTERNAL_ENV value', CYPRESS_INTERNAL_ENV) diff --git a/cli/lib/tasks/download.js b/cli/lib/tasks/download.js index 6b8cd38b69b2..17b6c733f301 100644 --- a/cli/lib/tasks/download.js +++ b/cli/lib/tasks/download.js @@ -40,13 +40,7 @@ const getBaseUrl = () => { const getCA = () => { return new Promise((resolve) => { - if (!util.getEnv('CYPRESS_DOWNLOAD_USE_CA')) { - resolve() - } - - if (process.env.npm_config_ca) { - resolve(process.env.npm_config_ca) - } else if (process.env.npm_config_cafile) { + if (process.env.npm_config_cafile) { fs.readFile(process.env.npm_config_cafile, 'utf8') .then((cafileContent) => { resolve(cafileContent) @@ -54,6 +48,8 @@ const getCA = () => { .catch(() => { resolve() }) + } else if (process.env.npm_config_ca) { + resolve(process.env.npm_config_ca) } else { resolve() } diff --git a/cli/lib/util.js b/cli/lib/util.js index 5604e313c23a..6c42b3f58780 100644 --- a/cli/lib/util.js +++ b/cli/lib/util.js @@ -134,7 +134,7 @@ function isValidCypressInternalEnvValue (value) { return true } - // names of config environments, see "packages/server/config/app.yml" + // names of config environments, see "packages/server/config/app.json" const names = ['development', 'test', 'staging', 'production'] return _.includes(names, value) @@ -257,7 +257,7 @@ const getApplicationDataFolder = (...paths) => { const { env } = process // allow overriding the app_data folder - let folder = env.CYPRESS_KONFIG_ENV || env.CYPRESS_INTERNAL_ENV || 'development' + let folder = env.CYPRESS_CONFIG_ENV || env.CYPRESS_INTERNAL_ENV || 'development' const PRODUCT_NAME = pkg.productName || pkg.name const OS_DATA_PATH = ospath.data() diff --git a/cli/package.json b/cli/package.json index 0cb51269c791..a9f70660e5ec 100644 --- a/cli/package.json +++ b/cli/package.json @@ -16,6 +16,7 @@ "test-unit": "yarn unit", "test-watch": "yarn unit --watch", "types": "yarn dtslint", + "lint": "eslint --ext .js,.jsx,.ts,.tsx,.json,.vue .", "unit": "cross-env BLUEBIRD_DEBUG=1 NODE_ENV=test mocha --reporter mocha-multi-reporters --reporter-options configFile=../mocha-reporter-config.json" }, "dependencies": { diff --git a/cli/test/lib/tasks/download_spec.js b/cli/test/lib/tasks/download_spec.js index 13c1176795b4..7617cdcd4ebe 100644 --- a/cli/test/lib/tasks/download_spec.js +++ b/cli/test/lib/tasks/download_spec.js @@ -607,7 +607,7 @@ describe('lib/tasks/download', function () { // prevent ambient environment masking of environment variables referenced in this test ;([ - 'CYPRESS_DOWNLOAD_USE_CA', 'NO_PROXY', 'http_proxy', + 'NO_PROXY', 'http_proxy', 'https_proxy', 'npm_config_ca', 'npm_config_cafile', 'npm_config_https_proxy', 'npm_config_proxy', ]).forEach((e) => { @@ -683,7 +683,6 @@ describe('lib/tasks/download', function () { }) it('returns CA from npm_config_ca', () => { - process.env.CYPRESS_DOWNLOAD_USE_CA = 'true' process.env.npm_config_ca = 'foo' return download.getCA().then((ca) => { @@ -692,7 +691,6 @@ describe('lib/tasks/download', function () { }) it('returns CA from npm_config_cafile', () => { - process.env.CYPRESS_DOWNLOAD_USE_CA = 'true' process.env.npm_config_cafile = 'test/fixture/cafile.pem' return download.getCA().then((ca) => { @@ -701,7 +699,6 @@ describe('lib/tasks/download', function () { }) it('returns undefined if failed reading npm_config_cafile', () => { - process.env.CYPRESS_DOWNLOAD_USE_CA = 'true' process.env.npm_config_cafile = 'test/fixture/not-exists.pem' return download.getCA().then((ca) => { diff --git a/cli/types/cypress-npm-api.d.ts b/cli/types/cypress-npm-api.d.ts index 269889d6ffd0..126f50202863 100644 --- a/cli/types/cypress-npm-api.d.ts +++ b/cli/types/cypress-npm-api.d.ts @@ -60,7 +60,7 @@ declare namespace CypressCommandLine { */ headless: boolean /** - * Specify your secret record key + * Specify your secret Record Key */ key: string /** diff --git a/cli/types/cypress.d.ts b/cli/types/cypress.d.ts index 15df81c5986d..537d598c7625 100644 --- a/cli/types/cypress.d.ts +++ b/cli/types/cypress.d.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ /// /// /// @@ -395,7 +396,7 @@ declare namespace Cypress { }) ``` */ - config(Object: ConfigOptions): void + config(Object: TestConfigOverrides): void // no real way to type without generics /** @@ -470,19 +471,19 @@ declare namespace Cypress { add(name: T, options: CommandOptions & {prevSubject: false}, fn: CommandFn): void add(name: T, options: CommandOptions & {prevSubject: true}, fn: CommandFnWithSubject): void add( - name: T, options: CommandOptions & { prevSubject: S | ['optional'] }, fn: CommandFnWithSubject, + name: T, options: CommandOptions & { prevSubject: S | ['optional'] }, fn: CommandFnWithSubject, ): void add( - name: T, options: CommandOptions & { prevSubject: S[] }, fn: CommandFnWithSubject[S]>, + name: T, options: CommandOptions & { prevSubject: S[] }, fn: CommandFnWithSubject[S]>, ): void addAll(fns: CommandFns): void addAll(options: CommandOptions & {prevSubject: false}, fns: CommandFns): void addAll(options: CommandOptions & { prevSubject: true }, fns: CommandFnsWithSubject): void addAll( - options: CommandOptions & { prevSubject: S | ['optional'] }, fns: CommandFnsWithSubject, + options: CommandOptions & { prevSubject: S | ['optional'] }, fns: CommandFnsWithSubject, ): void addAll( - options: CommandOptions & { prevSubject: S[] }, fns: CommandFnsWithSubject[S]>, + options: CommandOptions & { prevSubject: S[] }, fns: CommandFnsWithSubject[S]>, ): void overwrite(name: T, fn: CommandFnWithOriginalFn): void overwrite(name: T, fn: CommandFnWithOriginalFnAndSubject): void @@ -641,12 +642,6 @@ declare namespace Cypress { */ off: Actions - /** - * Used to import dependencies within the cy.origin() callback - * @see https://on.cypress.io/origin - */ - require: (id: string) => any - /** * Trigger action * @private @@ -676,14 +671,14 @@ declare namespace Cypress { * If validation fails after restoring a session, `setup` will re-run. * @default {false} */ - validate?: () => Promise | false | void + validate?: () => Promise | void } type CanReturnChainable = void | Chainable | Promise type ThenReturn = R extends void ? Chainable : - R extends R | undefined ? Chainable> : - Chainable + R extends R | undefined ? Chainable> : + Chainable /** * Chainable interface for non-array Subjects @@ -781,20 +776,20 @@ declare namespace Cypress { clear(options?: Partial): Chainable /** - * Clear a specific browser cookie. + * Clear a specific browser cookie for the current superdomain or for the domain specified. * Cypress automatically clears all cookies before each test to prevent state from being shared across tests. You shouldn't need to use this command unless you're using it to clear a specific cookie inside a single test. * * @see https://on.cypress.io/clearcookie */ - clearCookie(name: string, options?: Partial): Chainable + clearCookie(name: string, options?: CookieOptions): Chainable /** - * Clear all browser cookies. - * Cypress automatically clears all cookies before each test to prevent state from being shared across tests. You shouldn't need to use this command unless you're using it to clear a specific cookie inside a single test. + * Clear all browser cookies for the current superdomain or for the domain specified. + * Cypress automatically clears all cookies before each test to prevent state from being shared across tests. You shouldn't need to use this command unless you're using it to clear all cookies or specific cookies inside a single test. * * @see https://on.cypress.io/clearcookies */ - clearCookies(options?: Partial): Chainable + clearCookies(options?: CookieOptions): Chainable /** * Clear data in local storage. @@ -1095,7 +1090,7 @@ declare namespace Cypress { * * @see https://on.cypress.io/session */ - session(id: string | object, setup?: () => void, options?: SessionOptions): Chainable + session(id: string | object, setup: () => void, options?: SessionOptions): Chainable /** * Get the window.document of the page that is currently active. @@ -1254,18 +1249,18 @@ declare namespace Cypress { get(alias: string, options?: Partial): Chainable /** - * Get a browser cookie by its name. + * Get a browser cookie by its name for the current superdomain or for the domain specified. * * @see https://on.cypress.io/getcookie */ - getCookie(name: string, options?: Partial): Chainable + getCookie(name: string, options?: CookieOptions): Chainable /** - * Get all of the browser cookies. + * Get all of the browser cookies for the current superdomain or for the domain specified. * * @see https://on.cypress.io/getcookies */ - getCookies(options?: Partial): Chainable + getCookies(options?: CookieOptions): Chainable /** * Navigate back or forward to the previous or next URL in the browser's history. @@ -2379,8 +2374,8 @@ declare namespace Cypress { type ChainableMethods = { [P in keyof Chainable]: Chainable[P] extends ((...args: any[]) => any) - ? Chainable[P] - : never + ? Chainable[P] + : never } interface SinonSpyAgent { @@ -2639,6 +2634,14 @@ declare namespace Cypress { cmdKey: boolean } + interface CookieOptions extends Partial { + /** + * Domain to set cookies on or get cookies from + * @default superdomain of the current app under test + */ + domain?: string + } + interface PEMCert { /** * Path to the certificate file, relative to project root. @@ -2814,12 +2817,32 @@ declare namespace Cypress { */ supportFile: string | false /** - * The test isolation level applied to ensure a clean slate between tests. - * - legacy - resets/clears aliases, intercepts, clock, viewport, cookies, and local storage before each test. - * - strict - applies all resets/clears from legacy, plus clears the page by visiting 'about:blank' to ensure clean app state before each test. - * @default "legacy", however, when experimentalSessionAndOrigin=true, the default is "strict" + * The test isolation ensures a clean browser context between tests. This option is only available when + * `experimentalSessionAndOrigin=true`. + * + * Cypress will always reset/clear aliases, intercepts, clock, and viewport before each test + * to ensure a clean test slate; i.e. this configuration only impacts the browser context. + * + * Note: the [`cy.session()`](https://on.cypress.io/session) command will inherent this value to determine whether + * or not the page is cleared when the command executes. This command is only available in end-to-end testing. + * + * - on - The page is cleared before each test. Cookies, local storage and session storage in all domains are cleared + * before each test. The `cy.session()` command will also clear the page and current browser context when creating + * or restoring the browser session. + * - off - The current browser state will persist between tests. The page does not clear before the test and cookies, local + * storage and session storage will be available in the next test. The `cy.session()` command will only clear the + * current browser context when creating or restoring the browser session - the current page will not clear. + * + * Tradeoffs: + * Turning test isolation off may improve performance of end-to-end tests, however, previous tests could impact the + * browser state of the next test and cause inconsistency when using .only(). Be mindful to write isolated tests when + * test isolation is off. If a test in the suite impacts the state of other tests and it were to fail, you could see + * misleading errors in later tests which makes debugging clunky. See the [documentation](https://on.cypress.io/test-isolation) + * for more information. + * + * @default null, when experimentalSessionAndOrigin=false. The default is 'on' when experimentalSessionAndOrigin=true. */ - testIsolation: 'legacy' | 'strict' + testIsolation: null | 'on' | 'off' /** * Path to folder where videos will be saved after a headless or CI run * @default "cypress/videos" @@ -2841,7 +2864,7 @@ declare namespace Cypress { */ video: boolean /** - * Whether Cypress will upload the video to the Dashboard even if all tests are passing. This applies only when recording your runs to the Dashboard. Turn this off if you'd like the video uploaded only when there are failing tests. + * Whether Cypress will upload the video to Cypress Cloud even if all tests are passing. This applies only when recording your runs to Cypress Cloud. Turn this off if you'd like the video uploaded only when there are failing tests. * @default true */ videoUploadOnPasses: boolean @@ -3052,7 +3075,16 @@ declare namespace Cypress { xhrUrl: string } - interface TestConfigOverrides extends Partial>, Partial> { + interface SuiteConfigOverrides extends Partial< + Pick + >, Partial> { + browser?: IsBrowserMatcher | IsBrowserMatcher[] + keystrokeDelay?: number + } + + interface TestConfigOverrides extends Partial< + Pick + >, Partial> { browser?: IsBrowserMatcher | IsBrowserMatcher[] keystrokeDelay?: number } @@ -3081,8 +3113,8 @@ declare namespace Cypress { type PickConfigOpt = T extends keyof DefineDevServerConfig ? DefineDevServerConfig[T] : any interface AngularDevServerProjectConfig { - root: string, - sourceRoot: string, + root: string + sourceRoot: string buildOptions: Record } @@ -3131,7 +3163,7 @@ declare namespace Cypress { /** * Hosts mappings to IP addresses. */ - hosts?: null | {[key: string]: string} + hosts?: null | {[key: string]: string} } interface PluginConfigOptions extends ResolvedConfigOptions, RuntimeConfigOptions { @@ -6057,7 +6089,7 @@ declare namespace Mocha { * Describe a "suite" with the given `title`, TestOptions, and callback `fn` containing * nested suites. */ - (title: string, config: Cypress.TestConfigOverrides, fn: (this: Suite) => void): Suite + (title: string, config: Cypress.SuiteConfigOverrides, fn: (this: Suite) => void): Suite } interface ExclusiveSuiteFunction { @@ -6065,10 +6097,10 @@ declare namespace Mocha { * Describe a "suite" with the given `title`, TestOptions, and callback `fn` containing * nested suites. Indicates this suite should be executed exclusively. */ - (title: string, config: Cypress.TestConfigOverrides, fn: (this: Suite) => void): Suite + (title: string, config: Cypress.SuiteConfigOverrides, fn: (this: Suite) => void): Suite } interface PendingSuiteFunction { - (title: string, config: Cypress.TestConfigOverrides, fn: (this: Suite) => void): Suite | void + (title: string, config: Cypress.SuiteConfigOverrides, fn: (this: Suite) => void): Suite | void } } diff --git a/cli/types/tests/cypress-tests.ts b/cli/types/tests/cypress-tests.ts index f13753aedc71..2119c9acd35f 100644 --- a/cli/types/tests/cypress-tests.ts +++ b/cli/types/tests/cypress-tests.ts @@ -34,11 +34,12 @@ namespace CypressConfigTests { // setters Cypress.config('baseUrl', '.') // $ExpectType void - Cypress.config({ e2e: { baseUrl: '.' }}) // $ExpectType void - Cypress.config({ e2e: { baseUrl: null }}) // $ExpectType void - Cypress.config({ e2e: { baseUrl: '.', }}) // $ExpectType void + Cypress.config({ e2e: { baseUrl: '.' }}) // $ExpectError + Cypress.config({ e2e: { baseUrl: null }}) // $ExpectError + Cypress.config({ e2e: { baseUrl: '.', }}) // $ExpectError Cypress.config({ component: { baseUrl: '.', devServer: () => ({} as any) } }) // $ExpectError Cypress.config({ e2e: { indexHtmlFile: 'index.html' } }) // $ExpectError + Cypress.config({ testIsolation: 'off' }) // $ExpectError Cypress.config('taskTimeout') // $ExpectType number Cypress.config('includeShadowDom') // $ExpectType boolean @@ -866,6 +867,9 @@ namespace CypressTestConfigOverridesTests { it('test', { retries: { run: 3 } // $ExpectError }, () => { }) + it('test', { + testIsolation: 'off', // $ExpectError + }, () => { }) it.skip('test', {}, () => {}) it.only('test', {}, () => {}) @@ -882,6 +886,10 @@ namespace CypressTestConfigOverridesTests { keystrokeDelay: 0 }, () => {}) + describe('suite', { + testIsolation: 'off', + }, () => {}) + context('suite', {}, () => {}) describe('suite', { @@ -922,7 +930,6 @@ namespace CypressTaskTests { } namespace CypressSessionsTests { - cy.session('user') cy.session('user', () => {}) cy.session({ name: 'bob' }, () => {}) cy.session('user', () => {}, {}) @@ -931,11 +938,13 @@ namespace CypressSessionsTests { }) cy.session() // $ExpectError + cy.session('user') // $ExpectError cy.session(null) // $ExpectError cy.session('user', () => {}, { validate: { foo: true } // $ExpectError }) } + namespace CypressCurrentTest { Cypress.currentTest.title // $ExpectType string Cypress.currentTest.titlePath // $ExpectType string[] @@ -974,3 +983,82 @@ namespace CypressOriginTests { cy.origin('example.com', { args: ['value'] }, (value: boolean[]) => {}) // $ExpectError cy.origin('example.com', {}, (value: undefined) => {}) // $ExpectError } + +namespace CypressGetCookiesTests { + cy.getCookies().then((cookies) => { + cookies // $ExpectType Cookie[] + }) + cy.getCookies({ log: true }) + cy.getCookies({ timeout: 10 }) + cy.getCookies({ domain: 'localhost' }) + cy.getCookies({ log: true, timeout: 10, domain: 'localhost' }) + + cy.getCookies({ log: 'true' }) // $ExpectError + cy.getCookies({ timeout: '10' }) // $ExpectError + cy.getCookies({ domain: false }) // $ExpectError +} + +namespace CypressGetCookieTests { + cy.getCookie('name').then((cookie) => { + cookie // $ExpectType Cookie | null + }) + cy.getCookie('name', { log: true }) + cy.getCookie('name', { timeout: 10 }) + cy.getCookie('name', { domain: 'localhost' }) + cy.getCookie('name', { log: true, timeout: 10, domain: 'localhost' }) + + cy.getCookie('name', { log: 'true' }) // $ExpectError + cy.getCookie('name', { timeout: '10' }) // $ExpectError + cy.getCookie('name', { domain: false }) // $ExpectError +} + +namespace CypressSetCookieTests { + cy.setCookie('name', 'value').then((cookie) => { + cookie // $ExpectType Cookie + }) + cy.setCookie('name', 'value', { log: true }) + cy.setCookie('name', 'value', { timeout: 10 }) + cy.setCookie('name', 'value', { + domain: 'localhost', + path: '/', + secure: true, + httpOnly: false, + expiry: 12345, + sameSite: 'lax', + }) + cy.setCookie('name', 'value', { log: true, timeout: 10, domain: 'localhost' }) + + cy.setCookie('name') // $ExpectError + cy.setCookie('name', 'value', { log: 'true' }) // $ExpectError + cy.setCookie('name', 'value', { timeout: '10' }) // $ExpectError + cy.setCookie('name', 'value', { domain: false }) // $ExpectError + cy.setCookie('name', 'value', { foo: 'bar' }) // $ExpectError +} + +namespace CypressClearCookieTests { + cy.clearCookie('name').then((result) => { + result // $ExpectType null + }) + cy.clearCookie('name', { log: true }) + cy.clearCookie('name', { timeout: 10 }) + cy.clearCookie('name', { domain: 'localhost' }) + cy.clearCookie('name', { log: true, timeout: 10, domain: 'localhost' }) + + cy.clearCookie('name', { log: 'true' }) // $ExpectError + cy.clearCookie('name', { timeout: '10' }) // $ExpectError + cy.clearCookie('name', { domain: false }) // $ExpectError +} + +namespace CypressClearCookiesTests { + cy.clearCookies().then((result) => { + result // $ExpectType null + }) + cy.clearCookies({ log: true }) + cy.clearCookies({ timeout: 10 }) + cy.clearCookies({ domain: 'localhost' }) + cy.clearCookies({ log: true, timeout: 10, domain: 'localhost' }) + + cy.clearCookies({ log: 'true' }) // $ExpectError + cy.clearCookies({ timeout: '10' }) // $ExpectError + cy.clearCookies({ domain: false }) // $ExpectError +} diff --git a/cli/types/tsconfig.json b/cli/types/tsconfig.json index 8bb09ec24448..5e9ac0d8af41 100644 --- a/cli/types/tsconfig.json +++ b/cli/types/tsconfig.json @@ -5,6 +5,7 @@ "dom", "es6" ], + "exactOptionalPropertyTypes": true, "noImplicitAny": true, "noImplicitThis": true, "strictNullChecks": true, diff --git a/cypress-prioritization-and-triage.md b/cypress-prioritization-and-triage.md index 43cd97413570..7a5fb2ce79e9 100644 --- a/cypress-prioritization-and-triage.md +++ b/cypress-prioritization-and-triage.md @@ -118,7 +118,7 @@ There are a number of reasons why a ticket may be closed without any change or P The best place for asking questions is our [Discord server](https://discord.gg/cypress) which has a very active community of folks with a diverse set of knowledge. Other available channels to explore include [Cypress GitHub discussions](https://github.com/cypress-io/cypress/discussions), [community chat](https://on.cypress.io/chat), and [Stack Overflow](https://stackoverflow.com/questions/tagged/cypress). We also offer support via email with our [paid plans](https://www.cypress.io/pricing/). -- **Feature request for Cypress Dashboard** - Thank you for your support as a Cypress Dashboard user! These issues are routed to our Cypress Dashboard team's ticketing system. Your customer success representative is available for follow-up and will reach out you directly via email if more information is needed. +- **Feature request for Cypress Cloud** - Thank you for your support as a Cypress Cloud user! These issues are routed to our Cypress Cloud team's ticketing system. Your customer success representative is available for follow-up and will reach out you directly via email if more information is needed. - **The fix or feature is not within our vision for Cypress** - There will inevitably be suggestions that will not fit within the scope of Cypress' vision for our product. We will do our best to explain why we will not be addressing this issue. diff --git a/graphql-codegen.yml b/graphql-codegen.yml index 496238eb8d1d..e2b11c51214b 100644 --- a/graphql-codegen.yml +++ b/graphql-codegen.yml @@ -18,7 +18,7 @@ vueOperations: &vueOperations - 'typescript-operations' - 'typed-document-node': # Intentionally specified under typed-document-node rather than top level config, - # becuase we don't want it flattening the types for the operations + # because we don't want it flattening the types for the operations flattenGeneratedTypes: true vueTesting: &vueTesting @@ -122,9 +122,10 @@ generates: './packages/app/src/generated/graphql-test.ts': documents: - './packages/app/src/**/*.{vue,ts,tsx,js,jsx}' - - './packages/frontend-shared/src/**/*.{vue,ts,tsx,js,jsx}' + - './packages/frontend-shared/src/gql-components/**/*.{vue,ts,tsx,js,jsx}' <<: *vueTesting './packages/frontend-shared/src/generated/graphql-test.ts': - documents: './packages/frontend-shared/src/gql-components/**/*.{vue,ts,tsx,js,jsx}' + documents: + - './packages/frontend-shared/src/gql-components/**/*.{vue,ts,tsx,js,jsx}' <<: *vueTesting diff --git a/guides/release-process.md b/guides/release-process.md index dd309fea4c96..a23d5724599c 100644 --- a/guides/release-process.md +++ b/guides/release-process.md @@ -82,7 +82,7 @@ In the following instructions, "X.Y.Z" is used to denote the [next version of Cy - Go into a project, run a quick test, make sure things look right - Optionally, install the new version into an established project and run the tests there - [cypress-realworld-app](https://github.com/cypress-io/cypress-realworld-app) uses yarn and represents a typical consumer implementation. - - Optionally, do more thorough tests, for example test the new version of Cypress against the Cypress dashboard repo. + - Optionally, do more thorough tests, for example test the new version of Cypress against the Cypress Cloud repo. 5. Log into AWS SSO with `aws sso login --profile `. If you have setup your credentials under a different profile than `prod`, be sure to set the `AWS_PROFILE` environment variable to that profile name for the remaining steps. For example, if you are using `production` instead of `prod`, do `export AWS_PROFILE=production`. @@ -119,7 +119,7 @@ In the following instructions, "X.Y.Z" is used to denote the [next version of Cy - Go into a project, run a quick test, make sure things look right - Install the new version into an established project and run the tests there - [cypress-realworld-app](https://github.com/cypress-io/cypress-realworld-app) uses yarn and represents a typical consumer implementation. - - Optionally, do more thorough tests, for example test the new version of Cypress against the Cypress dashboard repo. + - Optionally, do more thorough tests, for example test the new version of Cypress against the Cypress Cloud repo. 11. Create or review the release-specific documentation and changelog in [cypress-documentation](https://github.com/cypress-io/cypress-documentation). If there is not already a release-specific PR open, create one. This PR must be merged, built, and deployed before moving to the next step. - Use [`release-automations`](https://github.com/cypress-io/release-automations)'s `issues-in-release` tool to generate a starting point for the changelog, based off of ZenHub: diff --git a/jsconfig.json b/jsconfig.json index 5f354257acc6..8313f340090b 100644 --- a/jsconfig.json +++ b/jsconfig.json @@ -10,6 +10,7 @@ "**/build/**", "**/dist/**", "**/dist-test/**", - "**/.cy/**" + "**/.cy/**", + "**/v8-snapshot/cache/**" ] } diff --git a/lerna.json b/lerna.json index e541ef2d7385..f40b1af11f4c 100644 --- a/lerna.json +++ b/lerna.json @@ -4,6 +4,7 @@ "cli", "packages/*", "npm/*", + "tooling/*", "system-tests" ], "useWorkspaces": true, diff --git a/npm/angular/.eslintignore b/npm/angular/.eslintignore new file mode 100644 index 000000000000..79afe972da7d --- /dev/null +++ b/npm/angular/.eslintignore @@ -0,0 +1,5 @@ +**/dist +**/*.d.ts +**/package-lock.json +**/tsconfig.json +**/cypress/fixtures \ No newline at end of file diff --git a/npm/angular/CHANGELOG.md b/npm/angular/CHANGELOG.md index 48915a2619d0..f81c22d0854c 100644 --- a/npm/angular/CHANGELOG.md +++ b/npm/angular/CHANGELOG.md @@ -1,3 +1,30 @@ +# [@cypress/angular-v2.0.1](https://github.com/cypress-io/cypress/compare/@cypress/angular-v2.0.0...@cypress/angular-v2.0.1) (2022-11-08) + + +### Bug Fixes + +* make component derived info not throw ([#24571](https://github.com/cypress-io/cypress/issues/24571)) ([838dd4f](https://github.com/cypress-io/cypress/commit/838dd4fa2e0ec56633d0af2faf10a47d190b5594)) + +# [@cypress/angular-v2.0.0](https://github.com/cypress-io/cypress/compare/@cypress/angular-v1.1.2...@cypress/angular-v2.0.0) (2022-11-07) + + +### Bug Fixes + +* possibility to override global services in Angular component tests ([#24394](https://github.com/cypress-io/cypress/issues/24394)) ([54d2853](https://github.com/cypress-io/cypress/commit/54d285321723450920e0f1d50374c4bd0590e72a)) +* remove last mounted component upon subsequent mount calls ([#24470](https://github.com/cypress-io/cypress/issues/24470)) ([f39eb1c](https://github.com/cypress-io/cypress/commit/f39eb1c19e0923bda7ae263168fc6448da942d54)) + + +### BREAKING CHANGES + +* remove last mounted component upon subsequent mount calls of mount + +# [@cypress/angular-v1.1.2](https://github.com/cypress-io/cypress/compare/@cypress/angular-v1.1.1...@cypress/angular-v1.1.2) (2022-10-11) + + +### Bug Fixes + +* angular and nuxt ct tests now fail on uncaught exceptions ([#24122](https://github.com/cypress-io/cypress/issues/24122)) ([53eef4f](https://github.com/cypress-io/cypress/commit/53eef4fbd7e1caf32f0183cadbc0e4cf05524c34)) + # [@cypress/angular-v1.1.1](https://github.com/cypress-io/cypress/compare/@cypress/angular-v1.1.0...@cypress/angular-v1.1.1) (2022-10-04) diff --git a/npm/angular/README.md b/npm/angular/README.md index 8537799fabcf..2e75bfe830b1 100644 --- a/npm/angular/README.md +++ b/npm/angular/README.md @@ -1,85 +1,10 @@ # @cypress/angular -Mount Angular components in the open source [Cypress.io](https://www.cypress.io/) test runner **v7.0.0+** - -> **Note:** This package is bundled with the `cypress` package and should not need to be installed separately. See the [Angular Component Testing Docs](https://docs.cypress.io/guides/component-testing/quickstart-angular#Configuring-Component-Testing) for mounting Angular components. Installing and importing `mount` from `@cypress/angular` should only be used for advanced use-cases. - -## Install - -- Requires Cypress v7.0.0 or later -- Requires [Node](https://nodejs.org/en/) version 12 or above - -```sh -npm install --save-dev @cypress/angular -``` - -## Run - -Open cypress test runner -``` -npx cypress open --component -``` - -If you need to run test in CI -``` -npx cypress run --component -``` - -For more information, please check the official docs for [running Cypress](https://on.cypress.io/guides/getting-started/opening-the-app#Quick-Configuration) and for [component testing](https://on.cypress.io/guides/component-testing/writing-your-first-component-test). - -## API - -- `mount` is the most important function, allows to mount a given Angular component as a mini web application and interact with it using Cypress commands -- `MountConfig` Configuration used to configure your test -- `createOutputSpy` factory function that creates new EventEmitter for your component and spies on it's `emit` method. - -## Examples - -```ts -import { mount } from '@cypress/angular' -import { HelloWorldComponent } from './hello-world.component' - -describe('HelloWorldComponent', () => { - it('works', () => { - mount(HelloWorldComponent) - // now use standard Cypress commands - cy.contains('Hello World!').should('be.visible') - }) -}) -``` - -```ts -import { mount } from '@cypress/angular' -import { HelloWorldComponent } from './hello-world.component' - -describe('HelloWorldComponent', () => { - it('works', () => { - mount('', { - declarations: [HelloWorldComponent] - }) - // now use standard Cypress commands - cy.contains('Hello World!').should('be.visible') - }) -}) -``` - -Look at the examples in [cypress-component-testing-apps](https://github.com/cypress-io/cypress-component-testing-apps) repo. Here in the `angular` and `angular-standalone` folders are the two example applications showing various testing scenarios. - - -## Compatibility - -| @cypress/angular | cypress | -| -------------- | ------- | -| >= v1 | >= v10.5 | +Mount Angular components in the open source [Cypress.io](https://www.cypress.io/) test runner +> **Note:** This package is bundled with the `cypress` package and should not need to be installed separately. See the [Angular Component Testing Docs](https://docs.cypress.io/guides/component-testing/angular/overview) for mounting Angular components. Installing and importing `mount` from `@cypress/angular` should only be done for advanced use-cases. ## Development Run `yarn build` to compile and sync packages to the `cypress` cli package. -## License - -[![license](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/cypress-io/cypress/blob/develop/LICENSE) - -This project is licensed under the terms of the [MIT license](/LICENSE). - ## [Changelog](./CHANGELOG.md) diff --git a/npm/angular/package.json b/npm/angular/package.json index 72cc5afaec3d..206047edca16 100644 --- a/npm/angular/package.json +++ b/npm/angular/package.json @@ -8,7 +8,8 @@ "build": "rollup -c rollup.config.mjs", "postbuild": "node ../../scripts/sync-exported-npm-with-cli.js", "build-prod": "yarn build", - "check-ts": "tsc --noEmit" + "check-ts": "tsc --noEmit", + "lint": "eslint --ext .js,.ts,.json, ." }, "dependencies": {}, "devDependencies": { diff --git a/npm/angular/src/mount.ts b/npm/angular/src/mount.ts index 0743f3aa0bc8..4ea70537f858 100644 --- a/npm/angular/src/mount.ts +++ b/npm/angular/src/mount.ts @@ -8,7 +8,7 @@ window.Mocha['__zone_patch__'] = false import 'zone.js/testing' import { CommonModule } from '@angular/common' -import { Component, EventEmitter, SimpleChange, SimpleChanges, Type } from '@angular/core' +import { Component, ErrorHandler, EventEmitter, Injectable, SimpleChange, SimpleChanges, Type, OnChanges } from '@angular/core' import { ComponentFixture, getTestBed, @@ -72,6 +72,23 @@ export interface MountConfig extends TestModuleMetadata { componentProperties?: Partial<{ [P in keyof T]: T[P] }> } +let activeFixture: ComponentFixture | null = null + +function cleanup () { + // Not public, we need to call this to remove the last component from the DOM + try { + (getTestBed() as any).tearDownTestingModule() + } catch (e) { + const notSupportedError = new Error(`Failed to teardown component. The version of Angular you are using may not be officially supported.`) + + ;(notSupportedError as any).docsUrl = 'https://on.cypress.io/component-framework-configuration' + throw notSupportedError + } + + getTestBed().resetTestingModule() + activeFixture = null +} + /** * Type that the `mount` function returns * @type MountResponse @@ -99,6 +116,13 @@ export type MountResponse = { // so we'll patch here pending a fix in that library globalThis.it.skip = globalThis.xit +@Injectable() +class CypressAngularErrorHandler implements ErrorHandler { + handleError (error: Error): void { + throw error + } +} + /** * Bootstraps the TestModuleMetaData passed to the TestBed * @@ -120,8 +144,19 @@ function bootstrapModule ( testModuleMetaData.imports = [] } + if (!testModuleMetaData.providers) { + testModuleMetaData.providers = [] + } + + // Replace default error handler since it will swallow uncaught exceptions. + // We want these to be uncaught so Cypress catches it and fails the test + testModuleMetaData.providers.push({ + provide: ErrorHandler, + useClass: CypressAngularErrorHandler, + }) + // check if the component is a standalone component - if ((component as any).ɵcmp.standalone) { + if ((component as any).ɵcmp?.standalone) { testModuleMetaData.imports.push(component) } else { testModuleMetaData.declarations.push(component) @@ -145,22 +180,12 @@ function initTestBed ( component: Type | string, config: MountConfig, ): Type { - const { providers, ...configRest } = config - const componentFixture = createComponentFixture(component) as Type getTestBed().configureTestingModule({ - ...bootstrapModule(componentFixture, configRest), + ...bootstrapModule(componentFixture, config), }) - if (providers != null) { - getTestBed().overrideComponent(componentFixture, { - add: { - providers, - }, - }) - } - return componentFixture } @@ -201,6 +226,8 @@ function setupFixture ( ): ComponentFixture { const fixture = getTestBed().createComponent(component) + setupComponent(config, fixture) + fixture.whenStable().then(() => { fixture.autoDetectChanges(config.autoDetectChanges ?? true) }) @@ -215,17 +242,18 @@ function setupFixture ( * @param {ComponentFixture} fixture Fixture for debugging and testing a component. * @returns {T} Component being mounted */ -function setupComponent ( +function setupComponent ( config: MountConfig, - fixture: ComponentFixture): T { - let component: T = fixture.componentInstance + fixture: ComponentFixture, +): void { + let component = fixture.componentInstance as unknown as { [key: string]: any } & Partial if (config?.componentProperties) { component = Object.assign(component, config.componentProperties) } if (config.autoSpyOutputs) { - Object.keys(component).forEach((key: string, index: number, keys: string[]) => { + Object.keys(component).forEach((key) => { const property = component[key] if (property instanceof EventEmitter) { @@ -244,56 +272,61 @@ function setupComponent 0) { component.ngOnChanges(simpleChanges) } } - - return component } /** * Mounts an Angular component inside Cypress browser * - * @param {Type | string} component Angular component being mounted or its template - * @param {MountConfig} config configuration used to configure the TestBed + * @param component Angular component being mounted or its template + * @param config configuration used to configure the TestBed * @example - * import { HelloWorldComponent } from 'hello-world/hello-world.component' + * import { mount } from '@cypress/angular' + * import { StepperComponent } from './stepper.component' * import { MyService } from 'services/my.service' * import { SharedModule } from 'shared/shared.module'; - * import { mount } from '@cypress/angular' - * it('can mount', () => { - * mount(HelloWorldComponent, { - * providers: [MyService], - * imports: [SharedModule] - * }) - * cy.get('h1').contains('Hello World') + * it('mounts', () => { + * mount(StepperComponent, { + * providers: [MyService], + * imports: [SharedModule] + * }) + * cy.get('[data-cy=increment]').click() + * cy.get('[data-cy=counter]').should('have.text', '1') * }) * - * or + * // or * - * it('can mount with template', () => { - * mount('', { - * declarations: [HelloWorldComponent], - * providers: [MyService], - * imports: [SharedModule] - * }) + * it('mounts with template', () => { + * mount('', { + * declarations: [StepperComponent], + * }) * }) - * @returns Cypress.Chainable> + * + * @see {@link https://on.cypress.io/mounting-angular} for more details. + * + * @returns A component and component fixture */ export function mount ( component: Type | string, config: MountConfig = { }, ): Cypress.Chainable> { + // Remove last mounted component if cy.mount is called more than once in a test + if (activeFixture) { + cleanup() + } + const componentFixture = initTestBed(component, config) - const fixture = setupFixture(componentFixture, config) - const componentInstance = setupComponent(config, fixture) + + activeFixture = setupFixture(componentFixture, config) const mountResponse: MountResponse = { - fixture, - component: componentInstance, + fixture: activeFixture, + component: activeFixture.componentInstance, } const logMessage = typeof component === 'string' ? 'Component' : componentFixture.name @@ -312,6 +345,15 @@ export function mount ( * * @param {string} alias name you want to use for your cy.spy() alias * @returns EventEmitter + * @example + * import { StepperComponent } from './stepper.component' + * import { mount, createOutputSpy } from '@cypress/angular' + * + * it('Has spy', () => { + * mount(StepperComponent, { change: createOutputSpy('changeSpy') }) + * cy.get('[data-cy=increment]').click() + * cy.get('@changeSpy').should('have.been.called') + * }) */ export const createOutputSpy = (alias: string) => { const emitter = new EventEmitter() @@ -330,8 +372,4 @@ getTestBed().initTestEnvironment( }, ) -setupHooks(() => { - // Not public, we need to call this to remove the last component from the DOM - getTestBed()['tearDownTestingModule']() - getTestBed().resetTestingModule() -}) +setupHooks(cleanup) diff --git a/npm/angular/tsconfig.json b/npm/angular/tsconfig.json index b21ac64dacea..a73e01dcecc9 100644 --- a/npm/angular/tsconfig.json +++ b/npm/angular/tsconfig.json @@ -11,15 +11,15 @@ "allowJs": true, "declaration": true, "outDir": "dist", - "strict": false, - "noImplicitAny": false, + "strict": true, "baseUrl": "./", "types": [ "cypress" ], "allowSyntheticDefaultImports": true, "esModuleInterop": true, - "moduleResolution": "node" + "moduleResolution": "node", + "noPropertyAccessFromIndexSignature": true, }, "include": ["src/**/*.*"], "exclude": ["src/**/*-spec.*"] diff --git a/npm/create-cypress-tests/.eslintignore b/npm/create-cypress-tests/.eslintignore new file mode 100644 index 000000000000..341078756065 --- /dev/null +++ b/npm/create-cypress-tests/.eslintignore @@ -0,0 +1,9 @@ +**/dist +**/*.d.ts +**/package-lock.json +**/tsconfig.json +**/cypress/fixtures +**/test/fixtures +**/__snapshots__ +/initial-template +/**/*.template.* \ No newline at end of file diff --git a/npm/create-cypress-tests/package.json b/npm/create-cypress-tests/package.json index d6b0456c8f4c..969dff7c97c6 100644 --- a/npm/create-cypress-tests/package.json +++ b/npm/create-cypress-tests/package.json @@ -9,7 +9,8 @@ "prepare-example": "node scripts/example copy-to ./initial-template", "prepare-copy-templates": "node scripts/copy-templates copy-to ./dist/src", "test": "cross-env TS_NODE_PROJECT=./tsconfig.test.json mocha --config .mocharc.json './src/**/*.test.ts'", - "test:watch": "yarn test -w" + "test:watch": "yarn test -w", + "lint": "eslint --ext .js,.ts,.json, ." }, "dependencies": { "@babel/core": "^7.5.4", diff --git a/npm/cypress-schematic/.eslintignore b/npm/cypress-schematic/.eslintignore new file mode 100644 index 000000000000..79afe972da7d --- /dev/null +++ b/npm/cypress-schematic/.eslintignore @@ -0,0 +1,5 @@ +**/dist +**/*.d.ts +**/package-lock.json +**/tsconfig.json +**/cypress/fixtures \ No newline at end of file diff --git a/npm/cypress-schematic/CHANGELOG.md b/npm/cypress-schematic/CHANGELOG.md index 5ff7e93b67ec..d6834f375ad8 100644 --- a/npm/cypress-schematic/CHANGELOG.md +++ b/npm/cypress-schematic/CHANGELOG.md @@ -1,114 +1,21 @@ -# [@cypress/schematic-v2.1.0](https://github.com/cypress-io/cypress/compare/@cypress/schematic-v2.0.3...@cypress/schematic-v2.1.0) (2022-10-04) - - -### Bug Fixes - -* angular 14.2 mount compilation error ([#23593](https://github.com/cypress-io/cypress/issues/23593)) ([2f337db](https://github.com/cypress-io/cypress/commit/2f337dbfa2bb212754c8fa82e3f4548a2f3a07a4)) -* Detect user-configured browsers ([#23446](https://github.com/cypress-io/cypress/issues/23446)) ([a75d3ec](https://github.com/cypress-io/cypress/commit/a75d3ec81f3405db6721a89875d89cdca0109013)) - - -### Features - -* _addQuery() ([#23665](https://github.com/cypress-io/cypress/issues/23665)) ([41fc535](https://github.com/cypress-io/cypress/commit/41fc535dca51cda4e40b5d9fc827d8bff534f3d1)) -* **cypress/schematic:** add support for component testing ([#23385](https://github.com/cypress-io/cypress/issues/23385)) ([99562af](https://github.com/cypress-io/cypress/commit/99562af65a10abb0fab211fd97b13f98e2b0f959)) - -# [@cypress/schematic-v2.1.0](https://github.com/cypress-io/cypress/compare/@cypress/schematic-v2.0.3...@cypress/schematic-v2.1.0) (2022-10-04) - - -### Bug Fixes - -* angular 14.2 mount compilation error ([#23593](https://github.com/cypress-io/cypress/issues/23593)) ([2f337db](https://github.com/cypress-io/cypress/commit/2f337dbfa2bb212754c8fa82e3f4548a2f3a07a4)) -* Detect user-configured browsers ([#23446](https://github.com/cypress-io/cypress/issues/23446)) ([a75d3ec](https://github.com/cypress-io/cypress/commit/a75d3ec81f3405db6721a89875d89cdca0109013)) - - -### Features - -* _addQuery() ([#23665](https://github.com/cypress-io/cypress/issues/23665)) ([41fc535](https://github.com/cypress-io/cypress/commit/41fc535dca51cda4e40b5d9fc827d8bff534f3d1)) -* **cypress/schematic:** add support for component testing ([#23385](https://github.com/cypress-io/cypress/issues/23385)) ([99562af](https://github.com/cypress-io/cypress/commit/99562af65a10abb0fab211fd97b13f98e2b0f959)) - -# [@cypress/schematic-v2.1.0](https://github.com/cypress-io/cypress/compare/@cypress/schematic-v2.0.3...@cypress/schematic-v2.1.0) (2022-10-03) - - -### Bug Fixes - -* angular 14.2 mount compilation error ([#23593](https://github.com/cypress-io/cypress/issues/23593)) ([2f337db](https://github.com/cypress-io/cypress/commit/2f337dbfa2bb212754c8fa82e3f4548a2f3a07a4)) -* Detect user-configured browsers ([#23446](https://github.com/cypress-io/cypress/issues/23446)) ([a75d3ec](https://github.com/cypress-io/cypress/commit/a75d3ec81f3405db6721a89875d89cdca0109013)) - - -### Features - -* _addQuery() ([#23665](https://github.com/cypress-io/cypress/issues/23665)) ([41fc535](https://github.com/cypress-io/cypress/commit/41fc535dca51cda4e40b5d9fc827d8bff534f3d1)) -* **cypress/schematic:** add support for component testing ([#23385](https://github.com/cypress-io/cypress/issues/23385)) ([99562af](https://github.com/cypress-io/cypress/commit/99562af65a10abb0fab211fd97b13f98e2b0f959)) - -# [@cypress/schematic-v2.1.0](https://github.com/cypress-io/cypress/compare/@cypress/schematic-v2.0.3...@cypress/schematic-v2.1.0) (2022-10-01) - - -### Bug Fixes - -* angular 14.2 mount compilation error ([#23593](https://github.com/cypress-io/cypress/issues/23593)) ([2f337db](https://github.com/cypress-io/cypress/commit/2f337dbfa2bb212754c8fa82e3f4548a2f3a07a4)) -* Detect user-configured browsers ([#23446](https://github.com/cypress-io/cypress/issues/23446)) ([a75d3ec](https://github.com/cypress-io/cypress/commit/a75d3ec81f3405db6721a89875d89cdca0109013)) - - -### Features - -* _addQuery() ([#23665](https://github.com/cypress-io/cypress/issues/23665)) ([41fc535](https://github.com/cypress-io/cypress/commit/41fc535dca51cda4e40b5d9fc827d8bff534f3d1)) -* **cypress/schematic:** add support for component testing ([#23385](https://github.com/cypress-io/cypress/issues/23385)) ([99562af](https://github.com/cypress-io/cypress/commit/99562af65a10abb0fab211fd97b13f98e2b0f959)) - -# [@cypress/schematic-v2.1.0](https://github.com/cypress-io/cypress/compare/@cypress/schematic-v2.0.3...@cypress/schematic-v2.1.0) (2022-09-30) - - -### Bug Fixes - -* angular 14.2 mount compilation error ([#23593](https://github.com/cypress-io/cypress/issues/23593)) ([2f337db](https://github.com/cypress-io/cypress/commit/2f337dbfa2bb212754c8fa82e3f4548a2f3a07a4)) -* Detect user-configured browsers ([#23446](https://github.com/cypress-io/cypress/issues/23446)) ([a75d3ec](https://github.com/cypress-io/cypress/commit/a75d3ec81f3405db6721a89875d89cdca0109013)) - - -### Features - -* _addQuery() ([#23665](https://github.com/cypress-io/cypress/issues/23665)) ([41fc535](https://github.com/cypress-io/cypress/commit/41fc535dca51cda4e40b5d9fc827d8bff534f3d1)) -* **cypress/schematic:** add support for component testing ([#23385](https://github.com/cypress-io/cypress/issues/23385)) ([99562af](https://github.com/cypress-io/cypress/commit/99562af65a10abb0fab211fd97b13f98e2b0f959)) - -# [@cypress/schematic-v2.1.0](https://github.com/cypress-io/cypress/compare/@cypress/schematic-v2.0.3...@cypress/schematic-v2.1.0) (2022-09-30) - - -### Bug Fixes - -* angular 14.2 mount compilation error ([#23593](https://github.com/cypress-io/cypress/issues/23593)) ([2f337db](https://github.com/cypress-io/cypress/commit/2f337dbfa2bb212754c8fa82e3f4548a2f3a07a4)) -* Detect user-configured browsers ([#23446](https://github.com/cypress-io/cypress/issues/23446)) ([a75d3ec](https://github.com/cypress-io/cypress/commit/a75d3ec81f3405db6721a89875d89cdca0109013)) - - -### Features - -* _addQuery() ([#23665](https://github.com/cypress-io/cypress/issues/23665)) ([41fc535](https://github.com/cypress-io/cypress/commit/41fc535dca51cda4e40b5d9fc827d8bff534f3d1)) -* **cypress/schematic:** add support for component testing ([#23385](https://github.com/cypress-io/cypress/issues/23385)) ([99562af](https://github.com/cypress-io/cypress/commit/99562af65a10abb0fab211fd97b13f98e2b0f959)) - -# [@cypress/schematic-v2.1.0](https://github.com/cypress-io/cypress/compare/@cypress/schematic-v2.0.3...@cypress/schematic-v2.1.0) (2022-09-30) - - -### Bug Fixes - -* angular 14.2 mount compilation error ([#23593](https://github.com/cypress-io/cypress/issues/23593)) ([2f337db](https://github.com/cypress-io/cypress/commit/2f337dbfa2bb212754c8fa82e3f4548a2f3a07a4)) -* Detect user-configured browsers ([#23446](https://github.com/cypress-io/cypress/issues/23446)) ([a75d3ec](https://github.com/cypress-io/cypress/commit/a75d3ec81f3405db6721a89875d89cdca0109013)) +# [@cypress/schematic-v2.3.0](https://github.com/cypress-io/cypress/compare/@cypress/schematic-v2.2.0...@cypress/schematic-v2.3.0) (2022-11-01) ### Features -* _addQuery() ([#23665](https://github.com/cypress-io/cypress/issues/23665)) ([41fc535](https://github.com/cypress-io/cypress/commit/41fc535dca51cda4e40b5d9fc827d8bff534f3d1)) -* **cypress/schematic:** add support for component testing ([#23385](https://github.com/cypress-io/cypress/issues/23385)) ([99562af](https://github.com/cypress-io/cypress/commit/99562af65a10abb0fab211fd97b13f98e2b0f959)) +* introduce v8 snapshots to improve startup performance ([#24295](https://github.com/cypress-io/cypress/issues/24295)) ([b0c0eaa](https://github.com/cypress-io/cypress/commit/b0c0eaa508bb6dafdc1997bc00fb7ed6f5bcc160)) -# [@cypress/schematic-v2.1.0](https://github.com/cypress-io/cypress/compare/@cypress/schematic-v2.0.3...@cypress/schematic-v2.1.0) (2022-09-29) +# [@cypress/schematic-v2.2.0](https://github.com/cypress-io/cypress/compare/@cypress/schematic-v2.1.1...@cypress/schematic-v2.2.0) (2022-10-13) ### Bug Fixes -* angular 14.2 mount compilation error ([#23593](https://github.com/cypress-io/cypress/issues/23593)) ([2f337db](https://github.com/cypress-io/cypress/commit/2f337dbfa2bb212754c8fa82e3f4548a2f3a07a4)) * Detect user-configured browsers ([#23446](https://github.com/cypress-io/cypress/issues/23446)) ([a75d3ec](https://github.com/cypress-io/cypress/commit/a75d3ec81f3405db6721a89875d89cdca0109013)) ### Features * _addQuery() ([#23665](https://github.com/cypress-io/cypress/issues/23665)) ([41fc535](https://github.com/cypress-io/cypress/commit/41fc535dca51cda4e40b5d9fc827d8bff534f3d1)) -* **cypress/schematic:** add support for component testing ([#23385](https://github.com/cypress-io/cypress/issues/23385)) ([99562af](https://github.com/cypress-io/cypress/commit/99562af65a10abb0fab211fd97b13f98e2b0f959)) # [@cypress/schematic-v2.1.1](https://github.com/cypress-io/cypress/compare/@cypress/schematic-v2.1.0...@cypress/schematic-v2.1.1) (2022-08-31) diff --git a/npm/cypress-schematic/README.md b/npm/cypress-schematic/README.md index bd61e4828164..c99fc139dd18 100644 --- a/npm/cypress-schematic/README.md +++ b/npm/cypress-schematic/README.md @@ -135,9 +135,9 @@ Before running Cypress in `open` mode, ensure that you have started your applica Read our docs to learn more about [launching browsers](https://on.cypress.io/launching-browsers) with Cypress. -### Recording test results to the Cypress Dashboard +### Recording test results to Cypress Cloud -We recommend setting your [Cypress Dashboard](https://on.cypress.io/features-dashboard) recording key as an environment variable and NOT as a builder option when running it in CI. +We recommend setting your [Cypress Cloud](https://on.cypress.io/features-dashboard) recording key as an environment variable and NOT as a builder option when running it in CI. ```json "cypress-run": { @@ -145,7 +145,7 @@ We recommend setting your [Cypress Dashboard](https://on.cypress.io/features-das "options": { "devServerTarget": "{project-name}:serve", "record": true, - "key": "your-cypress-dashboard-recording-key" + "key": "your-cypress-cloud-recording-key" }, "configurations": { "production": { @@ -155,7 +155,7 @@ We recommend setting your [Cypress Dashboard](https://on.cypress.io/features-das } ``` -Read our docs to learn more about [recording test results](https://on.cypress.io/recording-project-runs) to the [Cypress Dashboard](https://on.cypress.io/features-dashboard). +Read our docs to learn more about [recording test results](https://on.cypress.io/recording-project-runs) to [Cypress Cloud](https://on.cypress.io/features-dashboard). ### Specifying a custom config file @@ -187,7 +187,7 @@ Read our docs to learn more about all the [configuration options](https://on.cyp "devServerTarget": "{project-name}:serve", "parallel": true, "record": true, - "key": "your-cypress-dashboard-recording-key" + "key": "your-cypress-cloud-recording-key" }, "configurations": { "production": { diff --git a/npm/cypress-schematic/package.json b/npm/cypress-schematic/package.json index e1e8341e5e32..eb63ce1f7e9d 100644 --- a/npm/cypress-schematic/package.json +++ b/npm/cypress-schematic/package.json @@ -6,7 +6,8 @@ "scripts": { "build": "tsc -p tsconfig.json", "build:watch": "tsc -p tsconfig.json --watch", - "test": "mocha -r @packages/ts/register --reporter mocha-multi-reporters --reporter-options configFile=../../mocha-reporter-config.json src/**/*.spec.ts" + "test": "mocha -r @packages/ts/register --reporter mocha-multi-reporters --reporter-options configFile=../../mocha-reporter-config.json src/**/*.spec.ts", + "lint": "eslint --ext .ts,.json, ." }, "dependencies": { "@angular-devkit/architect": "^0.1402.1", diff --git a/npm/cypress-schematic/src/ct.spec.ts b/npm/cypress-schematic/src/ct.spec.ts index ad2ca1d28a42..6eb58f30f9f5 100644 --- a/npm/cypress-schematic/src/ct.spec.ts +++ b/npm/cypress-schematic/src/ct.spec.ts @@ -9,7 +9,7 @@ const scaffoldAngularProject = async (project: string) => { Fixtures.removeProject(project) await Fixtures.scaffoldProject(project) - await FixturesScaffold.scaffoldProjectNodeModules(project) + await FixturesScaffold.scaffoldProjectNodeModules({ project }) await fs.remove(path.join(projectPath, 'cypress.config.ts')) await fs.remove(path.join(projectPath, 'cypress')) diff --git a/npm/cypress-schematic/src/e2e.spec.ts b/npm/cypress-schematic/src/e2e.spec.ts index add1d333e549..47bd3c434eed 100644 --- a/npm/cypress-schematic/src/e2e.spec.ts +++ b/npm/cypress-schematic/src/e2e.spec.ts @@ -9,7 +9,7 @@ const scaffoldAngularProject = async (project: string) => { Fixtures.removeProject(project) await Fixtures.scaffoldProject(project) - await FixturesScaffold.scaffoldProjectNodeModules(project) + await FixturesScaffold.scaffoldProjectNodeModules({ project }) await fs.remove(path.join(projectPath, 'cypress.config.ts')) await fs.remove(path.join(projectPath, 'cypress')) diff --git a/npm/grep/CHANGELOG.md b/npm/grep/CHANGELOG.md new file mode 100644 index 000000000000..88538b9d4ca8 --- /dev/null +++ b/npm/grep/CHANGELOG.md @@ -0,0 +1,6 @@ +# [@cypress/grep-v3.1.0](https://github.com/cypress-io/cypress/compare/@cypress/grep-v3.0.3...@cypress/grep-v3.1.0) (2022-10-21) + + +### Features + +* **grep:** move cypress-grep to @cypress/grep ([#23887](https://github.com/cypress-io/cypress/issues/23887)) ([d422aad](https://github.com/cypress-io/cypress/commit/d422aadfa10e5aaac17ed0e4dd5e18a73d821490)) diff --git a/npm/grep/README.md b/npm/grep/README.md index 9466d08098de..7114b854bed9 100644 --- a/npm/grep/README.md +++ b/npm/grep/README.md @@ -84,12 +84,12 @@ yarn add -D @cypress/grep ```js // cypress/support/index.js // load and register the grep feature using "require" function -// https://github.com/cypress-io/cypress-grep -const registerCypressGrep = require('cypress-grep') +// https://github.com/cypress-io/cypress/tree/develop/npm/grep +const registerCypressGrep = require('@cypress/grep') registerCypressGrep() // if you want to use the "import" keyword -import registerCypressGrep from 'cypress-grep' +import registerCypressGrep from '@cypress/grep' registerCypressGrep() ``` @@ -102,7 +102,7 @@ registerCypressGrep() { e2e: { setupNodeEvents(on, config) { - require('cypress-grep/src/plugin')(config); + require('@cypress/grep/src/plugin')(config); return config; }, } diff --git a/npm/grep/src/support.js b/npm/grep/src/support.js index 844ef51ecf0e..5fd42b5db588 100644 --- a/npm/grep/src/support.js +++ b/npm/grep/src/support.js @@ -4,7 +4,7 @@ const { parseGrep, shouldTestRun } = require('./utils') // @ts-ignore const { version } = require('../package.json') -const debug = require('debug')('cypress-grep') +const debug = require('debug')('@cypress/grep') debug.log = console.info.bind(console) diff --git a/npm/mount-utils/.eslintignore b/npm/mount-utils/.eslintignore new file mode 100644 index 000000000000..79afe972da7d --- /dev/null +++ b/npm/mount-utils/.eslintignore @@ -0,0 +1,5 @@ +**/dist +**/*.d.ts +**/package-lock.json +**/tsconfig.json +**/cypress/fixtures \ No newline at end of file diff --git a/npm/mount-utils/CHANGELOG.md b/npm/mount-utils/CHANGELOG.md index 2801a2922f82..97153754cebd 100644 --- a/npm/mount-utils/CHANGELOG.md +++ b/npm/mount-utils/CHANGELOG.md @@ -1,58 +1,16 @@ -# [@cypress/mount-utils-v2.1.0](https://github.com/cypress-io/cypress/compare/@cypress/mount-utils-v2.0.1...@cypress/mount-utils-v2.1.0) (2022-10-04) +# [@cypress/mount-utils-v3.0.0](https://github.com/cypress-io/cypress/compare/@cypress/mount-utils-v2.1.0...@cypress/mount-utils-v3.0.0) (2022-11-07) -### Features - -* adding svelte component testing support ([#23553](https://github.com/cypress-io/cypress/issues/23553)) ([f6eaad4](https://github.com/cypress-io/cypress/commit/f6eaad40e1836fa9db87c60defa5ae6f390c8fd8)) - -# [@cypress/mount-utils-v2.1.0](https://github.com/cypress-io/cypress/compare/@cypress/mount-utils-v2.0.1...@cypress/mount-utils-v2.1.0) (2022-10-04) - - -### Features - -* adding svelte component testing support ([#23553](https://github.com/cypress-io/cypress/issues/23553)) ([f6eaad4](https://github.com/cypress-io/cypress/commit/f6eaad40e1836fa9db87c60defa5ae6f390c8fd8)) - -# [@cypress/mount-utils-v2.1.0](https://github.com/cypress-io/cypress/compare/@cypress/mount-utils-v2.0.1...@cypress/mount-utils-v2.1.0) (2022-10-03) - - -### Features - -* adding svelte component testing support ([#23553](https://github.com/cypress-io/cypress/issues/23553)) ([f6eaad4](https://github.com/cypress-io/cypress/commit/f6eaad40e1836fa9db87c60defa5ae6f390c8fd8)) - -# [@cypress/mount-utils-v2.1.0](https://github.com/cypress-io/cypress/compare/@cypress/mount-utils-v2.0.1...@cypress/mount-utils-v2.1.0) (2022-10-01) - - -### Features - -* adding svelte component testing support ([#23553](https://github.com/cypress-io/cypress/issues/23553)) ([f6eaad4](https://github.com/cypress-io/cypress/commit/f6eaad40e1836fa9db87c60defa5ae6f390c8fd8)) - -# [@cypress/mount-utils-v2.1.0](https://github.com/cypress-io/cypress/compare/@cypress/mount-utils-v2.0.1...@cypress/mount-utils-v2.1.0) (2022-09-30) - - -### Features - -* adding svelte component testing support ([#23553](https://github.com/cypress-io/cypress/issues/23553)) ([f6eaad4](https://github.com/cypress-io/cypress/commit/f6eaad40e1836fa9db87c60defa5ae6f390c8fd8)) - -# [@cypress/mount-utils-v2.1.0](https://github.com/cypress-io/cypress/compare/@cypress/mount-utils-v2.0.1...@cypress/mount-utils-v2.1.0) (2022-09-30) - - -### Features - -* adding svelte component testing support ([#23553](https://github.com/cypress-io/cypress/issues/23553)) ([f6eaad4](https://github.com/cypress-io/cypress/commit/f6eaad40e1836fa9db87c60defa5ae6f390c8fd8)) - -# [@cypress/mount-utils-v2.1.0](https://github.com/cypress-io/cypress/compare/@cypress/mount-utils-v2.0.1...@cypress/mount-utils-v2.1.0) (2022-09-30) - - -### Features - -* adding svelte component testing support ([#23553](https://github.com/cypress-io/cypress/issues/23553)) ([f6eaad4](https://github.com/cypress-io/cypress/commit/f6eaad40e1836fa9db87c60defa5ae6f390c8fd8)) +### Bug Fixes -# [@cypress/mount-utils-v2.1.0](https://github.com/cypress-io/cypress/compare/@cypress/mount-utils-v2.0.1...@cypress/mount-utils-v2.1.0) (2022-09-29) +* remove dependence on @cypress/ types ([#24415](https://github.com/cypress-io/cypress/issues/24415)) ([58e0ab9](https://github.com/cypress-io/cypress/commit/58e0ab91604618ea6f75932622f7e66e419270e6)) +* remove last mounted component upon subsequent mount calls ([#24470](https://github.com/cypress-io/cypress/issues/24470)) ([f39eb1c](https://github.com/cypress-io/cypress/commit/f39eb1c19e0923bda7ae263168fc6448da942d54)) +* remove some CT functions and props ([#24419](https://github.com/cypress-io/cypress/issues/24419)) ([294985f](https://github.com/cypress-io/cypress/commit/294985f8b3e0fa00ed66d25f88c8814603766074)) -### Features +### BREAKING CHANGES -* adding svelte component testing support ([#23553](https://github.com/cypress-io/cypress/issues/23553)) ([f6eaad4](https://github.com/cypress-io/cypress/commit/f6eaad40e1836fa9db87c60defa5ae6f390c8fd8)) +* remove last mounted component upon subsequent mount calls of mount # [@cypress/mount-utils-v2.1.0](https://github.com/cypress-io/cypress/compare/@cypress/mount-utils-v2.0.1...@cypress/mount-utils-v2.1.0) (2022-08-30) diff --git a/npm/mount-utils/README.md b/npm/mount-utils/README.md index 014e4f3052d4..6ca97dc425f8 100644 --- a/npm/mount-utils/README.md +++ b/npm/mount-utils/README.md @@ -2,7 +2,7 @@ > **Note** this package is not meant to be used outside of cypress component testing. -This librares exports some shared types and utility functions designed to build adapters for components frameworks. +This library exports some shared types and utility functions designed to build adapters for components frameworks. It is used in: @@ -22,14 +22,11 @@ All the functionality used to create the first party Mount adapters is available - Receive a component as the first argument. This could be class, function etc - depends on the framework. - Return a Cypress Chainable (for example using `cy.wrap`) that resolves whatever is idiomatic for your framework +- Call `getContainerEl` to access the root DOM element In addition, we recommend that Mount Adapters: -- receive a second argument that extends `StyleOptions` from `@cypress/mount-utils` -- calls `injectStylesBeforeElement` from `@cypress/mount-utils` before mounting the component -- calls `setupHooks` to register the required lifecycle hooks for `@cypress/mount-utils` to work - -This will let the user inject styles `` and stylesheets ``, which is very useful for developing components. +- call `setupHooks` to register the required lifecycle hooks for `@cypress/mount-utils` to work ### Example Mount Adapter: Web Components @@ -39,9 +36,7 @@ Here's a simple yet realistic example of Mount Adapter targeting Web Components. import { ROOT_SELECTOR, setupHooks, - injectStylesBeforeElement, - getContainerEl, - StyleOptions + getContainerEl } from "@cypress/mount-utils"; Cypress.on("run:start", () => { @@ -69,8 +64,7 @@ function maybeRegisterComponent( } export function mount( - webComponent: CustomElementConstructor, - options?: Partial + webComponent: CustomElementConstructor ): Cypress.Chainable { // Get root selector defined in `cypress/support.component-index.html const $root = document.querySelector(ROOT_SELECTOR)!; @@ -83,9 +77,6 @@ export function mount( /// Register Web Component maybeRegisterComponent(name, webComponent); - // Inject user styles before mounting the component - injectStylesBeforeElement(options ?? {}, document, getContainerEl()) - // Render HTML containing component. $root.innerHTML = `<${name} id="root">`; @@ -100,8 +91,7 @@ export function mount( return cy.wrap(document.querySelector("#root"), { log: false }); } -// Setup Cypress lifecycle hooks. This tears down any styles -// injected by injectStylesBeforeElement, etc. +// Setup Cypress lifecycle hooks. setupHooks(); ``` @@ -131,14 +121,7 @@ export class WebCounter extends HTMLElement { describe('web-component.cy.ts', () => { it('playground', () => { - cy.mount(WebCounter, { - styles: ` - button { - background: lightblue; - color: white; - } - ` - }) + cy.mount(WebCounter) }) }) ``` diff --git a/npm/mount-utils/create-rollup-entry.mjs b/npm/mount-utils/create-rollup-entry.mjs index 2db5e4781262..f3b0de4d610c 100644 --- a/npm/mount-utils/create-rollup-entry.mjs +++ b/npm/mount-utils/create-rollup-entry.mjs @@ -4,6 +4,7 @@ import resolve from '@rollup/plugin-node-resolve' import commonjs from '@rollup/plugin-commonjs' import _ from 'lodash' import { readFileSync } from 'fs' +import dts from 'rollup-plugin-dts' const pkg = JSON.parse(readFileSync('./package.json')) @@ -33,7 +34,7 @@ export function createEntries (options) { check: format === 'es', tsconfigOverride: { compilerOptions: { - declaration: format === 'es', + declaration: false, target: 'es6', module: format === 'cjs' ? 'es2015' : 'esnext', }, @@ -67,5 +68,19 @@ export function createEntries (options) { console.log(`Building ${format}: ${finalConfig.output.file}`) return finalConfig - }) + }).concat([{ + input, + output: [{ file: 'dist/index.d.ts', format: 'es' }], + plugins: [ + dts({ respectExternal: true }), + { + name: 'cypress-types-reference', + // rollup-plugin-dts does not add '// ' like rollup-plugin-typescript2 did so we add it here. + renderChunk (...[code]) { + return `/// \n\n${code}` + }, + }, + ], + external: config.external || [], + }]) } diff --git a/npm/mount-utils/package.json b/npm/mount-utils/package.json index b171f80da79c..2f04a31b9be7 100644 --- a/npm/mount-utils/package.json +++ b/npm/mount-utils/package.json @@ -8,13 +8,15 @@ "postbuild": "node ../../scripts/sync-exported-npm-with-cli.js", "build-prod": "yarn build", "check-ts": "tsc --noEmit", - "watch": "tsc -w" + "watch": "tsc -w", + "lint": "eslint --ext .js,.ts,.json, ." }, "dependencies": {}, "devDependencies": { "@rollup/plugin-commonjs": "^17.1.0", "@rollup/plugin-node-resolve": "^11.1.1", "rollup": "^2.38.5", + "rollup-plugin-dts": "^4.2.3", "rollup-plugin-typescript2": "^0.29.0", "typescript": "^4.7.4" }, diff --git a/npm/mount-utils/src/index.ts b/npm/mount-utils/src/index.ts index 5593110bd505..ac22dbfe52b5 100644 --- a/npm/mount-utils/src/index.ts +++ b/npm/mount-utils/src/index.ts @@ -1,44 +1,10 @@ -/** - * Additional styles to inject into the document. - * A component might need 3rd party libraries from CDN, - * local CSS files and custom styles. - */ -export interface StyleOptions { - /** - * Creates element for each stylesheet - * @alias stylesheet - */ - stylesheets: string | string[] - /** - * Creates element for each stylesheet - * @alias stylesheets - */ - stylesheet: string | string[] - /** - * Creates element and inserts given CSS. - * @alias styles - */ - style: string | string[] - /** - * Creates element for each given CSS text. - * @alias style - */ - styles: string | string[] - /** - * Loads each file and creates a element - * with the loaded CSS - * @alias cssFile - */ - cssFiles: string | string[] - /** - * Single CSS file to load into a element - * @alias cssFile - */ - cssFile: string | string[] -} - export const ROOT_SELECTOR = '[data-cy-root]' +/** + * Gets the root element used to mount the component. + * @returns {HTMLElement} The root element + * @throws {Error} If the root element is not found + */ export const getContainerEl = (): HTMLElement => { const el = document.querySelector(ROOT_SELECTOR) @@ -49,159 +15,20 @@ export const getContainerEl = (): HTMLElement => { throw Error(`No element found that matches selector ${ROOT_SELECTOR}. Please add a root element with data-cy-root attribute to your "component-index.html" file so that Cypress can attach your component to the DOM.`) } -/** - * Remove any style or extra link elements from the iframe placeholder - * left from any previous test - * - */ -export function cleanupStyles () { - const styles = document.body.querySelectorAll('[data-cy=injected-style-tag]') - - styles.forEach((styleElement) => { - if (styleElement.parentElement) { - styleElement.parentElement.removeChild(styleElement) - } - }) - - const links = document.body.querySelectorAll('[data-cy=injected-stylesheet]') - - links.forEach((link) => { - if (link.parentElement) { - link.parentElement.removeChild(link) +export function checkForRemovedStyleOptions (mountingOptions: Record) { + for (const key of ['cssFile', 'cssFiles', 'style', 'styles', 'stylesheet', 'stylesheets'] as const) { + if (mountingOptions[key]) { + Cypress.utils.throwErrByPath('mount.removed_style_mounting_options', key) } - }) -} - -/** - * Insert links to external style resources. - */ -function insertStylesheets ( - stylesheets: string[], - document: Document, - el: HTMLElement | null, -) { - stylesheets.forEach((href) => { - const link = document.createElement('link') - - link.type = 'text/css' - link.rel = 'stylesheet' - link.href = href - link.dataset.cy = 'injected-stylesheet' - document.body.insertBefore(link, el) - }) -} - -/** - * Inserts a single stylesheet element - */ -function insertStyles (styles: string[], document: Document, el: HTMLElement | null) { - styles.forEach((style) => { - const styleElement = document.createElement('style') - - styleElement.dataset.cy = 'injected-style-tag' - styleElement.appendChild(document.createTextNode(style)) - document.body.insertBefore(styleElement, el) - }) -} - -function insertSingleCssFile ( - cssFilename: string, - document: Document, - el: HTMLElement | null, - log?: boolean, -) { - return cy.readFile(cssFilename, { log }).then((css) => { - const style = document.createElement('style') - - style.appendChild(document.createTextNode(css)) - document.body.insertBefore(style, el) - }) -} - -/** - * Reads the given CSS file from local file system - * and adds the loaded style text as an element. - */ -function insertLocalCssFiles ( - cssFilenames: string[], - document: Document, - el: HTMLElement | null, - log?: boolean, -) { - return Cypress.Promise.mapSeries(cssFilenames, (cssFilename) => { - return insertSingleCssFile(cssFilename, document, el, log) - }) + } } /** - * Injects custom style text or CSS file or 3rd party style resources - * into the given document. + * Utility function to register CT side effects and run cleanup code during the "test:before:run" Cypress hook + * @param optionalCallback Callback to be called before the next test runs */ -export const injectStylesBeforeElement = ( - options: Partial, - document: Document, - el: HTMLElement | null, -): HTMLElement => { - if (!el) return - - // first insert all stylesheets as Link elements - let stylesheets: string[] = [] - - if (typeof options.stylesheet === 'string') { - stylesheets.push(options.stylesheet) - } else if (Array.isArray(options.stylesheet)) { - stylesheets = stylesheets.concat(options.stylesheet) - } - - if (typeof options.stylesheets === 'string') { - options.stylesheets = [options.stylesheets] - } - - if (options.stylesheets) { - stylesheets = stylesheets.concat(options.stylesheets) - } - - insertStylesheets(stylesheets, document, el) - - // insert any styles as elements - let styles: string[] = [] - - if (typeof options.style === 'string') { - styles.push(options.style) - } else if (Array.isArray(options.style)) { - styles = styles.concat(options.style) - } - - if (typeof options.styles === 'string') { - styles.push(options.styles) - } else if (Array.isArray(options.styles)) { - styles = styles.concat(options.styles) - } - - insertStyles(styles, document, el) - - // now load any css files by path and add their content - // as elements - let cssFiles: string[] = [] - - if (typeof options.cssFile === 'string') { - cssFiles.push(options.cssFile) - } else if (Array.isArray(options.cssFile)) { - cssFiles = cssFiles.concat(options.cssFile) - } - - if (typeof options.cssFiles === 'string') { - cssFiles.push(options.cssFiles) - } else if (Array.isArray(options.cssFiles)) { - cssFiles = cssFiles.concat(options.cssFiles) - } - - return insertLocalCssFiles(cssFiles, document, el, options.log) -} - export function setupHooks (optionalCallback?: Function) { - // Consumed by the framework "mount" libs. A user might register their own mount in the scaffolded 'commands.js' - // file that is imported by e2e and component support files by default. We don't want CT side effects to run when e2e + // We don't want CT side effects to run when e2e // testing so we early return. // System test to verify CT side effects do not pollute e2e: system-tests/test/e2e_with_mount_import_spec.ts if (Cypress.testingType !== 'component') { @@ -220,6 +47,41 @@ export function setupHooks (optionalCallback?: Function) { // @ts-ignore Cypress.on('test:before:run', () => { optionalCallback?.() - cleanupStyles() }) } + +/** + * Remove any style or extra link elements from the iframe placeholder + * left from any previous test + * + * Removed as of Cypress 11.0.0 + * @see https://on.cypress.io/migration-11-0-0-component-testing-updates + */ +export function cleanupStyles () { + Cypress.utils.throwErrByPath('mount.cleanup_styles') +} + +/** + * Additional styles to inject into the document. + * A component might need 3rd party libraries from CDN, + * local CSS files and custom styles. + * + * Removed as of Cypress 11.0.0. + * @see https://on.cypress.io/migration-11-0-0-component-testing-updates + */ +export type StyleOptions = unknown + +/** + * Injects custom style text or CSS file or 3rd party style resources + * into the given document. + * + * Removed as of Cypress 11.0.0. + * @see https://on.cypress.io/migration-11-0-0-component-testing-updates + */ +export const injectStylesBeforeElement = ( + options: Partial, + document: Document, + el: HTMLElement | null, +) => { + Cypress.utils.throwErrByPath('mount.inject_styles_before_element') +} diff --git a/npm/react/.eslintignore b/npm/react/.eslintignore new file mode 100644 index 000000000000..79afe972da7d --- /dev/null +++ b/npm/react/.eslintignore @@ -0,0 +1,5 @@ +**/dist +**/*.d.ts +**/package-lock.json +**/tsconfig.json +**/cypress/fixtures \ No newline at end of file diff --git a/npm/react/CHANGELOG.md b/npm/react/CHANGELOG.md index 05b69171570f..eb4ff6d9e418 100644 --- a/npm/react/CHANGELOG.md +++ b/npm/react/CHANGELOG.md @@ -1,58 +1,29 @@ -# [@cypress/react-v6.2.0](https://github.com/cypress-io/cypress/compare/@cypress/react-v6.1.1...@cypress/react-v6.2.0) (2022-10-04) +# [@cypress/react-v7.0.1](https://github.com/cypress-io/cypress/compare/@cypress/react-v7.0.0...@cypress/react-v7.0.1) (2022-11-08) -### Features - -* adding svelte component testing support ([#23553](https://github.com/cypress-io/cypress/issues/23553)) ([f6eaad4](https://github.com/cypress-io/cypress/commit/f6eaad40e1836fa9db87c60defa5ae6f390c8fd8)) - -# [@cypress/react-v6.2.0](https://github.com/cypress-io/cypress/compare/@cypress/react-v6.1.1...@cypress/react-v6.2.0) (2022-10-04) - - -### Features - -* adding svelte component testing support ([#23553](https://github.com/cypress-io/cypress/issues/23553)) ([f6eaad4](https://github.com/cypress-io/cypress/commit/f6eaad40e1836fa9db87c60defa5ae6f390c8fd8)) - -# [@cypress/react-v6.2.0](https://github.com/cypress-io/cypress/compare/@cypress/react-v6.1.1...@cypress/react-v6.2.0) (2022-10-03) - - -### Features - -* adding svelte component testing support ([#23553](https://github.com/cypress-io/cypress/issues/23553)) ([f6eaad4](https://github.com/cypress-io/cypress/commit/f6eaad40e1836fa9db87c60defa5ae6f390c8fd8)) - -# [@cypress/react-v6.2.0](https://github.com/cypress-io/cypress/compare/@cypress/react-v6.1.1...@cypress/react-v6.2.0) (2022-10-01) - - -### Features - -* adding svelte component testing support ([#23553](https://github.com/cypress-io/cypress/issues/23553)) ([f6eaad4](https://github.com/cypress-io/cypress/commit/f6eaad40e1836fa9db87c60defa5ae6f390c8fd8)) - -# [@cypress/react-v6.2.0](https://github.com/cypress-io/cypress/compare/@cypress/react-v6.1.1...@cypress/react-v6.2.0) (2022-09-30) - - -### Features - -* adding svelte component testing support ([#23553](https://github.com/cypress-io/cypress/issues/23553)) ([f6eaad4](https://github.com/cypress-io/cypress/commit/f6eaad40e1836fa9db87c60defa5ae6f390c8fd8)) +### Bug Fixes -# [@cypress/react-v6.2.0](https://github.com/cypress-io/cypress/compare/@cypress/react-v6.1.1...@cypress/react-v6.2.0) (2022-09-30) +* make component derived info not throw ([#24571](https://github.com/cypress-io/cypress/issues/24571)) ([838dd4f](https://github.com/cypress-io/cypress/commit/838dd4fa2e0ec56633d0af2faf10a47d190b5594)) +# [@cypress/react-v7.0.0](https://github.com/cypress-io/cypress/compare/@cypress/react-v6.2.1...@cypress/react-v7.0.0) (2022-11-07) -### Features -* adding svelte component testing support ([#23553](https://github.com/cypress-io/cypress/issues/23553)) ([f6eaad4](https://github.com/cypress-io/cypress/commit/f6eaad40e1836fa9db87c60defa5ae6f390c8fd8)) +### Bug Fixes -# [@cypress/react-v6.2.0](https://github.com/cypress-io/cypress/compare/@cypress/react-v6.1.1...@cypress/react-v6.2.0) (2022-09-30) +* remove last mounted component upon subsequent mount calls ([#24470](https://github.com/cypress-io/cypress/issues/24470)) ([f39eb1c](https://github.com/cypress-io/cypress/commit/f39eb1c19e0923bda7ae263168fc6448da942d54)) +* remove some CT functions and props ([#24419](https://github.com/cypress-io/cypress/issues/24419)) ([294985f](https://github.com/cypress-io/cypress/commit/294985f8b3e0fa00ed66d25f88c8814603766074)) -### Features +### BREAKING CHANGES -* adding svelte component testing support ([#23553](https://github.com/cypress-io/cypress/issues/23553)) ([f6eaad4](https://github.com/cypress-io/cypress/commit/f6eaad40e1836fa9db87c60defa5ae6f390c8fd8)) +* remove last mounted component upon subsequent mount calls of mount -# [@cypress/react-v6.2.0](https://github.com/cypress-io/cypress/compare/@cypress/react-v6.1.1...@cypress/react-v6.2.0) (2022-09-29) +# [@cypress/react-v6.2.1](https://github.com/cypress-io/cypress/compare/@cypress/react-v6.2.0...@cypress/react-v6.2.1) (2022-11-01) -### Features +### Bug Fixes -* adding svelte component testing support ([#23553](https://github.com/cypress-io/cypress/issues/23553)) ([f6eaad4](https://github.com/cypress-io/cypress/commit/f6eaad40e1836fa9db87c60defa5ae6f390c8fd8)) +* Hovering over mount in command log does not show component in AUT ([#24346](https://github.com/cypress-io/cypress/issues/24346)) ([355d210](https://github.com/cypress-io/cypress/commit/355d2101d38ea4d1e93b9c571cf77babab2bbbfc)) # [@cypress/react-v6.2.0](https://github.com/cypress-io/cypress/compare/@cypress/react-v6.1.1...@cypress/react-v6.2.0) (2022-08-30) diff --git a/npm/react/README.md b/npm/react/README.md index 23582443e447..bd5602adfd59 100644 --- a/npm/react/README.md +++ b/npm/react/README.md @@ -1,107 +1,8 @@ # @cypress/react -Mount React components in the open source [Cypress.io](https://www.cypress.io/) test runner **v7.0.0+** - -> **Note:** This package is bundled with the `cypress` package and should not need to be installed separately. See the [React Component Testing Docs](https://docs.cypress.io/guides/component-testing/quickstart-react#Configuring-Component-Testing) for mounting React components. Installing and importing `mount` from `@cypress/react` should only be used for advanced use-cases. - -## Install - -- Requires Cypress v7.0.0 or later -- Requires [Node](https://nodejs.org/en/) version 12 or above - -```sh -npm install --save-dev @cypress/react -``` - -## Run - -Open cypress test runner -``` -npx cypress open --component -``` - -If you need to run test in CI -``` -npx cypress run --component -``` - -For more information, please check the official docs for [running Cypress](https://on.cypress.io/guides/getting-started/opening-the-app#Quick-Configuration) and for [component testing](https://on.cypress.io/guides/component-testing/writing-your-first-component-test). - -## API - -- `mount` is the most important function, allows to mount a given React component as a mini web application and interact with it using Cypress commands -- `createMount` factory function that creates new `mount` function with default options -- `unmount` removes previously mounted component, mostly useful to test how the component cleans up after itself -- `mountHook` mounts a given React Hook in a test component for full testing, see `hooks` example - -## Examples - -```js -import React from 'react' -import { mount } from '@cypress/react' -import { HelloWorld } from './hello-world.jsx' -describe('HelloWorld component', () => { - it('works', () => { - mount() - // now use standard Cypress commands - cy.contains('Hello World!').should('be.visible') - }) -}) -``` - -Look at the examples in [cypress/component](cypress/component) folder. Here is the list of examples showing various testing scenarios. - -## Options - -In most cases, the component already imports its own styles, thus it looks "right" during the test. If you need another CSS, the simplest way is to import it from the spec file: - -```js -// src/Footer.spec.js -import './styles/main.css' -import Footer from './Footer' -it('looks right', () => { - // styles are applied - mount(