From 34043f99d989800c14f340b71f12d9d245d29a0c Mon Sep 17 00:00:00 2001 From: AtofStryker Date: Fri, 8 Nov 2024 12:33:45 -0500 Subject: [PATCH 1/2] breaking: remove support for react 16 and 17 for component testing and move cypress/react18 upstream into cypress/react [run ci] --- .circleci/cache-version.txt | 2 +- .circleci/workflows.yml | 10 +- CHANGELOG.md | 1 - CONTRIBUTING.md | 1 - cli/.eslintignore | 1 - cli/CHANGELOG.md | 6 +- cli/package.json | 7 - cli/scripts/post-build.js | 1 - .../app-action-example/counter.cy.jsx | 8 +- .../advanced/app-action-example/counter.jsx | 44 +- .../component/advanced/context/App.jsx | 20 +- .../advanced/mocking-axios/1-users.jsx | 49 +- ...{3-users-api.cy.jsx => 2-users-api.cy.jsx} | 4 +- .../advanced/mocking-axios/2-users-api.jsx | 29 ++ .../mocking-axios/2-users-named.cy.jsx | 36 -- .../advanced/mocking-axios/2-users-named.jsx | 33 -- .../advanced/mocking-axios/3-users-api.jsx | 34 -- .../advanced/renderless/mouse-movement.jsx | 66 ++- .../advanced/renderless/mouse.cy.jsx | 30 +- .../advanced/set-timeout-example/App.jsx | 46 +- .../set-timeout-example/LoadingIndicator.jsx | 43 +- .../advanced/timers/card-without-effect.jsx | 1 + .../advanced/tutorial/shopping-list.jsx | 24 +- .../component/advanced/tutorial/square.cy.jsx | 26 +- .../advanced/tutorial/tic-tac-toe.cy.jsx | 2 +- .../advanced/tutorial/tic-tac-toe.jsx | 186 ++++---- .../cypress/component/basic/css/Button.jsx | 30 +- .../cypress/component/basic/enzyme/README.md | 98 ---- .../component/basic/enzyme/context.cy.jsx | 53 --- .../component/basic/enzyme/props.cy.jsx | 82 ---- .../basic/enzyme/simple-component.jsx | 24 - .../component/basic/enzyme/simple-context.jsx | 4 - .../component/basic/enzyme/state.cy.jsx | 60 --- .../component/basic/network/1-users.jsx | 48 +- .../component/basic/network/2-users-fetch.jsx | 50 +- .../basic/react-tutorial/game.cy.jsx | 14 +- .../component/basic/react-tutorial/game.jsx | 178 +++---- .../basic/react-tutorial/shopping-list.jsx | 24 +- .../basic/react-tutorial/square1.jsx | 14 +- .../basic/react-tutorial/square2.jsx | 21 +- .../basic/react-tutorial/square3.jsx | 23 +- .../basic/react-tutorial/square4.jsx | 6 +- .../component/basic/rerender/effects.cy.jsx | 7 +- .../component/basic/unmount/comp.cy.jsx | 3 +- .../cypress/component/basic/unmount/comp.jsx | 18 +- .../component/basic/unmount/unmount.cy.jsx | 45 -- .../basic/use-render/my-component.jsx | 7 +- npm/react/package.json | 28 +- npm/react/src/mount.ts | 56 +-- npm/react/src/types.ts | 6 +- npm/react18/.eslintignore | 5 - npm/react18/.releaserc.js | 3 - npm/react18/CHANGELOG.md | 47 -- npm/react18/README.md | 7 - npm/react18/package.json | 71 --- npm/react18/rollup.config.mjs | 3 - npm/react18/src/index.ts | 92 ---- npm/react18/tsconfig.json | 22 - .../cypress/e2e/vite-dev-server.cy.ts | 2 +- npm/vite-plugin-cypress-esm/README.md | 12 +- npm/vite-plugin-cypress-esm/cypress.config.ts | 7 +- npm/vite-plugin-cypress-esm/package.json | 10 +- npm/vue/package.json | 3 - npm/webpack-preprocessor/package.json | 3 - .../cypress/e2e/config-warning.cy.ts | 4 +- .../reporter/cypress/support/component.ts | 2 +- packages/scaffold-config/src/dependencies.ts | 4 +- packages/scaffold-config/src/frameworks.ts | 14 +- .../test/unit/supportFile.spec.ts | 20 +- .../component_testing_spec.ts.js | 449 +----------------- .../react/cypress/support/component.js | 2 +- .../runner-specs/cypress/support/component.js | 2 +- .../src/NewComponent.spec.jsx | 2 +- .../src/TestComponent.spec.jsx | 2 +- .../vite/cypress/support/component.js | 2 +- .../webpack/cypress/support/component.js | 2 +- .../cypress/support/component.ts | 2 +- .../components/button.cy.jsx | 2 +- .../components/button.cy.jsx | 2 +- .../no-specs/cypress/support/component.js | 2 +- .../protocol/cypress/support/component.ts | 2 +- .../react-vite-ts-configured/src/App.cy.tsx | 2 +- .../react18/cypress/support/component.js | 2 +- .../react18/src/UsingLegacyMount.cy.jsx | 23 - .../projects/tailwind-vite/src/App.cy.jsx | 2 +- .../vite-simple/cypress/support/component.js | 2 +- .../src/relative-url.cy.jsx | 2 +- .../webpack5_wds4-react/src/App.cy.jsx | 2 +- .../webpack5_wds5-react/src/App.cy.jsx | 2 +- system-tests/test/component_testing_spec.ts | 4 +- yarn.lock | 217 ++------- 91 files changed, 619 insertions(+), 2050 deletions(-) rename npm/react/cypress/component/advanced/mocking-axios/{3-users-api.cy.jsx => 2-users-api.cy.jsx} (89%) create mode 100644 npm/react/cypress/component/advanced/mocking-axios/2-users-api.jsx delete mode 100644 npm/react/cypress/component/advanced/mocking-axios/2-users-named.cy.jsx delete mode 100644 npm/react/cypress/component/advanced/mocking-axios/2-users-named.jsx delete mode 100644 npm/react/cypress/component/advanced/mocking-axios/3-users-api.jsx delete mode 100644 npm/react/cypress/component/basic/enzyme/README.md delete mode 100644 npm/react/cypress/component/basic/enzyme/context.cy.jsx delete mode 100644 npm/react/cypress/component/basic/enzyme/props.cy.jsx delete mode 100644 npm/react/cypress/component/basic/enzyme/simple-component.jsx delete mode 100644 npm/react/cypress/component/basic/enzyme/simple-context.jsx delete mode 100644 npm/react/cypress/component/basic/enzyme/state.cy.jsx delete mode 100644 npm/react/cypress/component/basic/unmount/unmount.cy.jsx delete mode 100644 npm/react18/.eslintignore delete mode 100644 npm/react18/.releaserc.js delete mode 100644 npm/react18/CHANGELOG.md delete mode 100644 npm/react18/README.md delete mode 100644 npm/react18/package.json delete mode 100644 npm/react18/rollup.config.mjs delete mode 100644 npm/react18/src/index.ts delete mode 100644 npm/react18/tsconfig.json delete mode 100644 system-tests/projects/react18/src/UsingLegacyMount.cy.jsx diff --git a/.circleci/cache-version.txt b/.circleci/cache-version.txt index 0f616640a769..07249903be9c 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. -11-07-24-vue-cli-service-removal +11-07-24-react-16-17-removal diff --git a/.circleci/workflows.yml b/.circleci/workflows.yml index 31a194b14dab..1e29a0dc3da1 100644 --- a/.circleci/workflows.yml +++ b/.circleci/workflows.yml @@ -30,7 +30,7 @@ mainBuildFilters: &mainBuildFilters - /^release\/\d+\.\d+\.\d+$/ # use the following branch as well to ensure that v8 snapshot cache updates are fully tested - 'update-v8-snapshot-cache-on-develop' - - 'breaking/remove_vue_cli_service' + - 'breaking/remove_react_16_17_merge_react18_harness_upstream' - 'publish-binary' # usually we don't build Mac app - it takes a long time @@ -42,7 +42,7 @@ macWorkflowFilters: &darwin-workflow-filters - equal: [ develop, << pipeline.git.branch >> ] # use the following branch as well to ensure that v8 snapshot cache updates are fully tested - equal: [ 'update-v8-snapshot-cache-on-develop', << pipeline.git.branch >> ] - - equal: [ 'breaking/remove_vue_cli_service', << pipeline.git.branch >> ] + - equal: [ 'breaking/remove_react_16_17_merge_react18_harness_upstream', << pipeline.git.branch >> ] - matches: pattern: /^release\/\d+\.\d+\.\d+$/ value: << pipeline.git.branch >> @@ -53,7 +53,7 @@ linuxArm64WorkflowFilters: &linux-arm64-workflow-filters - equal: [ develop, << pipeline.git.branch >> ] # use the following branch as well to ensure that v8 snapshot cache updates are fully tested - equal: [ 'update-v8-snapshot-cache-on-develop', << pipeline.git.branch >> ] - - equal: [ 'breaking/remove_vue_cli_service', << pipeline.git.branch >> ] + - equal: [ 'breaking/remove_react_16_17_merge_react18_harness_upstream', << pipeline.git.branch >> ] - matches: pattern: /^release\/\d+\.\d+\.\d+$/ value: << pipeline.git.branch >> @@ -76,7 +76,7 @@ windowsWorkflowFilters: &windows-workflow-filters - equal: [ develop, << pipeline.git.branch >> ] # use the following branch as well to ensure that v8 snapshot cache updates are fully tested - equal: [ 'update-v8-snapshot-cache-on-develop', << pipeline.git.branch >> ] - - equal: [ 'breaking/remove_vue_cli_service', << pipeline.git.branch >> ] + - equal: [ 'breaking/remove_react_16_17_merge_react18_harness_upstream', << pipeline.git.branch >> ] - matches: pattern: /^release\/\d+\.\d+\.\d+$/ value: << pipeline.git.branch >> @@ -152,7 +152,7 @@ commands: name: Set environment variable to determine whether or not to persist artifacts command: | echo "Setting SHOULD_PERSIST_ARTIFACTS variable" - echo 'if ! [[ "$CIRCLE_BRANCH" != "develop" && "$CIRCLE_BRANCH" != "release/"* && "$CIRCLE_BRANCH" != "breaking/remove_vue_cli_service" ]]; then + echo 'if ! [[ "$CIRCLE_BRANCH" != "develop" && "$CIRCLE_BRANCH" != "release/"* && "$CIRCLE_BRANCH" != "breaking/remove_react_16_17_merge_react18_harness_upstream" ]]; then export SHOULD_PERSIST_ARTIFACTS=true fi' >> "$BASH_ENV" # You must run `setup_should_persist_artifacts` command and be using bash before running this command diff --git a/CHANGELOG.md b/CHANGELOG.md index 71f07af48ac9..ccf4888e233c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,6 @@ - [`@cypress/eslint-plugin-dev`](https://github.com/cypress-io/cypress/blob/develop/npm/eslint-plugin-dev/CHANGELOG.md) - [`@cypress/mount-utils`](https://github.com/cypress-io/cypress/blob/develop/npm/mount-utils/CHANGELOG.md) - [`@cypress/react`](https://github.com/cypress-io/cypress/blob/develop/npm/react/CHANGELOG.md) -- [`@cypress/react18`](https://github.com/cypress-io/cypress/blob/develop/npm/react18/CHANGELOG.md) - [`@cypress/svelte`](https://github.com/cypress-io/cypress/blob/develop/npm/svelte/CHANGELOG.md) - [`@cypress/vite-dev-server`](https://github.com/cypress-io/cypress/blob/develop/npm/vite-dev-server/CHANGELOG.md) - [`@cypress/vue`](https://github.com/cypress-io/cypress/blob/develop/npm/vue/CHANGELOG.md) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 530134c6218f..2077d1367b5c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -186,7 +186,6 @@ Here is a list of the npm packages in this repository: | [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. | diff --git a/cli/.eslintignore b/cli/.eslintignore index 9c171ae7d57e..90471aa76fd3 100644 --- a/cli/.eslintignore +++ b/cli/.eslintignore @@ -11,7 +11,6 @@ package.json # these are all copied from dist'd builds from the individual libs /angular /react -/react18 /vue /svelte /mount-utils \ No newline at end of file diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index 331fe0f4460f..699fe3d352a7 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -17,11 +17,13 @@ _Released 12/3/2024 (PENDING)_ - It is no longer possible to make a `fetch` or `XMLHttpRequest` request from the `about:blank` page in Electron (i.e. `cy.window().then((win) => win.fetch('')`). You must use `cy.request` instead or perform some form of initial navigation via `cy.visit()`. Addressed in [#29547](https://github.com/cypress-io/cypress/pull/30394). - `@cypress/webpack-dev-server` no longer supports `webpack-dev-server` version 3. Additionally, `@cypress/webpack-dev-server` now ships with `webpack-dev-server` version 5 by default. `webpack-dev-server` version 4 will need to be installed along side Cypress if you are still using `webpack` version 4. Addresses [#29308](https://github.com/cypress-io/cypress/issues/29308), [#30347](https://github.com/cypress-io/cypress/issues/30347), and [#30141](https://github.com/cypress-io/cypress/issues/30141). - `@cypress/vite-dev-server` no longer supports `vite` versions 2 and 3. Addresses [#29377](https://github.com/cypress-io/cypress/issues/29377) and [#29378](https://github.com/cypress-io/cypress/issues/29378). -- Cypress Component Testing no longer supports `Nuxt.js` version 2. Addresses [#30468](https://github.com/cypress-io/cypress/issues/30468). -- Cypress Component Testing no longer supports `Vue` version 2. Addresses [#30295](https://github.com/cypress-io/cypress/issues/30295). +- Cypress Component Testing no longer supports `React` versions 16 and 17. Addresses [#29607](https://github.com/cypress-io/cypress/issues/29607). - Cypress Component Testing no longer supports `Next.js` versions 10, 11, 12, and 13. Addresses [#29583](https://github.com/cypress-io/cypress/issues/29583). +- Cypress Component Testing no longer supports `Vue` version 2. Addresses [#30295](https://github.com/cypress-io/cypress/issues/30295). +- Cypress Component Testing no longer supports `Nuxt.js` version 2. Addresses [#30468](https://github.com/cypress-io/cypress/issues/30468). - Cypress Component Testing no longer supports `Angular` versions 13, 14, 15, and 16. The minimum supported version is now `17.2.0` in order to fully support Angular [signals](https://angular.dev/guide/signals). Addresses [#29582](https://github.com/cypress-io/cypress/issues/29582). Addressed in [#30539](https://github.com/cypress-io/cypress/pull/30539). - Cypress Component Testing no longer supports `Svelte` version 3. Addresses [#30492](https://github.com/cypress-io/cypress/issues/30492). +- The `cypress/react18` test harness is no longer included in the Cypress binary. Instead, React 18 support is now shipped with `cypress/react`! Addresses [#29607](https://github.com/cypress-io/cypress/issues/29607). - The `cypress/angular-signals` test harness is no longer included in the Cypress binary. Instead, signals support is now shipped with `cypress/angular`! This requires `rxjs` to be installed as a `peerDependency`. Addresses [#29606](https://github.com/cypress-io/cypress/issues/29606). - Cypress Component Testing no longer supports `create-react-app`. Addresses [#30028](https://github.com/cypress-io/cypress/issues/30028). - Cypress Component Testing no longer supports `@vue/cli-service`. Addresses [#30481](https://github.com/cypress-io/cypress/issues/30481). diff --git a/cli/package.json b/cli/package.json index 63ae512b0bf7..62377435c439 100644 --- a/cli/package.json +++ b/cli/package.json @@ -71,7 +71,6 @@ "@cypress/grep": "0.0.0-development", "@cypress/mount-utils": "0.0.0-development", "@cypress/react": "0.0.0-development", - "@cypress/react18": "0.0.0-development", "@cypress/sinon-chai": "2.9.1", "@cypress/svelte": "0.0.0-development", "@cypress/vue": "0.0.0-development", @@ -114,7 +113,6 @@ "mount-utils", "vue", "react", - "react18", "angular", "svelte" ], @@ -145,11 +143,6 @@ "import": "./react/dist/cypress-react.esm-bundler.js", "require": "./react/dist/cypress-react.cjs.js" }, - "./react18": { - "types": "./react18/dist/index.d.ts", - "import": "./react18/dist/cypress-react.esm-bundler.js", - "require": "./react18/dist/cypress-react.cjs.js" - }, "./mount-utils": { "types": "./mount-utils/dist/index.d.ts", "require": "./mount-utils/dist/index.js" diff --git a/cli/scripts/post-build.js b/cli/scripts/post-build.js index 4ee23008cf03..e31b9e2cf807 100644 --- a/cli/scripts/post-build.js +++ b/cli/scripts/post-build.js @@ -9,7 +9,6 @@ shell.set('-e') // any error is fatal const npmModulesToCopy = [ 'mount-utils', 'react', - 'react18', 'vue', 'angular', 'svelte', diff --git a/npm/react/cypress/component/advanced/app-action-example/counter.cy.jsx b/npm/react/cypress/component/advanced/app-action-example/counter.cy.jsx index 68caae19c867..bd7296290916 100644 --- a/npm/react/cypress/component/advanced/app-action-example/counter.cy.jsx +++ b/npm/react/cypress/component/advanced/app-action-example/counter.cy.jsx @@ -20,15 +20,13 @@ describe('Counter with access', () => { // the window.counter was set from the Counter's constructor cy.window() .should('have.property', 'counter') - .its('state') - .should('deep.equal', { count: 0 }) + .its('count') + .should('equal', 0) // let's change the state of the component cy.window() .its('counter') - .invoke('setState', { - count: 101, - }) + .invoke('setCount', 101) // the UI should update to reflect the new count cy.contains('count: 101').should('be.visible') diff --git a/npm/react/cypress/component/advanced/app-action-example/counter.jsx b/npm/react/cypress/component/advanced/app-action-example/counter.jsx index b300ff3106e5..1aed4d619089 100644 --- a/npm/react/cypress/component/advanced/app-action-example/counter.jsx +++ b/npm/react/cypress/component/advanced/app-action-example/counter.jsx @@ -1,34 +1,28 @@ -import React from 'react' +import React, { useState } from 'react' -export class Counter extends React.Component { - constructor (props) { - super(props) - this.state = { - count: 0, - } +export function Counter () { + const [count, setCount] = useState(0) - if (window.Cypress) { - // if this component is mounted from inside Cypress Test Runner - // then expose the reference to this instance - // to allow controlling it from tests - console.log( - 'set window.counter to this component in window', - window.location.pathname, - ) + if (window.Cypress) { + // if this component is mounted from inside Cypress Test Runner + // then expose the reference to this instance + // to allow controlling it from tests + console.log( + 'set window.counter to this component in window', + window.location.pathname, + ) - window.counter = this - } else { - console.log('running outside Cypress') + window.counter = { + count, + setCount, } + } else { + console.log('running outside Cypress') } - click = () => { - this.setState({ - count: this.state.count + 1, - }) + function click () { + setCount(count + 1) } - render () { - return

count: {this.state.count}

- } + return

count: {count}

} diff --git a/npm/react/cypress/component/advanced/context/App.jsx b/npm/react/cypress/component/advanced/context/App.jsx index 4620e6c38816..965e0a06815c 100644 --- a/npm/react/cypress/component/advanced/context/App.jsx +++ b/npm/react/cypress/component/advanced/context/App.jsx @@ -2,15 +2,13 @@ import React from 'react' import { ThemeContext } from './context' import { Toolbar } from './Toolbar.jsx' -export default class App extends React.Component { - render () { - // Use a Provider to pass the current theme to the tree below. - // Any component can read it, no matter how deep it is. - // In this example, we're passing "dark" as the current value. - return ( - - - - ) - } +export default function App () { + // Use a Provider to pass the current theme to the tree below. + // Any component can read it, no matter how deep it is. + // In this example, we're passing "dark" as the current value. + return ( + + + + ) } diff --git a/npm/react/cypress/component/advanced/mocking-axios/1-users.jsx b/npm/react/cypress/component/advanced/mocking-axios/1-users.jsx index 0b7081db11d3..0e896fa1d0ed 100644 --- a/npm/react/cypress/component/advanced/mocking-axios/1-users.jsx +++ b/npm/react/cypress/component/advanced/mocking-axios/1-users.jsx @@ -1,36 +1,29 @@ -import React from 'react' +import React, { useState, useEffect } from 'react' // import the entire axios module // later we can use axios.get to make requests import axios from 'axios' -export class Users extends React.Component { - constructor (props) { - super(props) - this.state = { - users: [], - } - } +export function Users () { + const [users, setUsers] = useState([]) - componentDidMount () { - axios - .get('https://jsonplaceholder.cypress.io/users?_limit=3') - .then((response) => { - // JSON responses are automatically parsed. - this.setState({ - users: response.data, - }) - }) - } + const getUsers = async () => { + const response = await axios.get('https://jsonplaceholder.cypress.io/users?_limit=3') + // JSON responses are automatically parsed. - render () { - return ( -
- {this.state.users.map((user) => ( -
  • - {user.id} - {user.name} -
  • - ))} -
    - ) + setUsers(response.data) } + + useEffect(() => { + getUsers() + }, []) + + return ( +
    + {users.map((user) => ( +
  • + {user.id} - {user.name} +
  • + ))} +
    + ) } diff --git a/npm/react/cypress/component/advanced/mocking-axios/3-users-api.cy.jsx b/npm/react/cypress/component/advanced/mocking-axios/2-users-api.cy.jsx similarity index 89% rename from npm/react/cypress/component/advanced/mocking-axios/3-users-api.cy.jsx rename to npm/react/cypress/component/advanced/mocking-axios/2-users-api.cy.jsx index 456c05112e1e..baa74cf22355 100644 --- a/npm/react/cypress/component/advanced/mocking-axios/3-users-api.cy.jsx +++ b/npm/react/cypress/component/advanced/mocking-axios/2-users-api.cy.jsx @@ -1,8 +1,8 @@ /// import React from 'react' import { mount } from '@cypress/react' -import { Users } from './3-users-api.jsx' -import * as axios from './axios-api' +import { Users } from './2-users-api.jsx' +import * as axios from './axios-api.jsx' describe('Mocking wrapped Axios', () => { it('shows real users', () => { diff --git a/npm/react/cypress/component/advanced/mocking-axios/2-users-api.jsx b/npm/react/cypress/component/advanced/mocking-axios/2-users-api.jsx new file mode 100644 index 000000000000..96fcbc13c075 --- /dev/null +++ b/npm/react/cypress/component/advanced/mocking-axios/2-users-api.jsx @@ -0,0 +1,29 @@ +import React, { useState, useEffect } from 'react' +// import wrapped Axios method +import axiosApi from './axios-api.jsx' + +export function Users () { + const [users, setUsers] = useState([]) + + const getUsers = async () => { + console.log({ axiosApi }) + const response = await axiosApi.get('https://jsonplaceholder.cypress.io/users?_limit=3') + // JSON responses are automatically parsed. + + setUsers(response.data) + } + + useEffect(() => { + getUsers() + }, []) + + return ( +
    + {users.map((user) => ( +
  • + {user.id} - {user.name} +
  • + ))} +
    + ) +} diff --git a/npm/react/cypress/component/advanced/mocking-axios/2-users-named.cy.jsx b/npm/react/cypress/component/advanced/mocking-axios/2-users-named.cy.jsx deleted file mode 100644 index bbb76f2db738..000000000000 --- a/npm/react/cypress/component/advanced/mocking-axios/2-users-named.cy.jsx +++ /dev/null @@ -1,36 +0,0 @@ -/// -import React from 'react' -import { mount } from '@cypress/react' -import { Users } from './2-users-named.jsx' -import axios from 'axios' - -describe('Mocking Axios named import get', () => { - it('shows real users', () => { - mount() - cy.get('li').should('have.length', 3) - }) - - // TODO: Support stubbing ES Modules - it.skip('mocks get', () => { - cy.stub(axios, 'get') - .resolves({ - data: [ - { - id: 101, - name: 'Test User', - }, - ], - }) - .as('get') - - mount() - // only the test user should be shown - cy.get('li').should('have.length', 1) - cy.get('@get').should('have.been.called') - }) - - it('restores the original method', () => { - mount() - cy.get('li').should('have.length', 3) - }) -}) diff --git a/npm/react/cypress/component/advanced/mocking-axios/2-users-named.jsx b/npm/react/cypress/component/advanced/mocking-axios/2-users-named.jsx deleted file mode 100644 index 11be902cda20..000000000000 --- a/npm/react/cypress/component/advanced/mocking-axios/2-users-named.jsx +++ /dev/null @@ -1,33 +0,0 @@ -import React from 'react' -// use named import "get" from the module -import { get } from 'axios' - -export class Users extends React.Component { - constructor (props) { - super(props) - this.state = { - users: [], - } - } - - componentDidMount () { - get('https://jsonplaceholder.cypress.io/users?_limit=3').then((response) => { - // JSON responses are automatically parsed. - this.setState({ - users: response.data, - }) - }) - } - - render () { - return ( -
    - {this.state.users.map((user) => ( -
  • - {user.id} - {user.name} -
  • - ))} -
    - ) - } -} diff --git a/npm/react/cypress/component/advanced/mocking-axios/3-users-api.jsx b/npm/react/cypress/component/advanced/mocking-axios/3-users-api.jsx deleted file mode 100644 index 3d7becfc5422..000000000000 --- a/npm/react/cypress/component/advanced/mocking-axios/3-users-api.jsx +++ /dev/null @@ -1,34 +0,0 @@ -import React from 'react' -// import wrapped Axios method -import axiosApi from './axios-api' - -export class Users extends React.Component { - constructor (props) { - super(props) - this.state = { - users: [], - } - } - - componentDidMount () { - console.log({ axiosApi }) - axiosApi.get('https://jsonplaceholder.cypress.io/users?_limit=3').then((response) => { - // JSON responses are automatically parsed. - this.setState({ - users: response.data, - }) - }) - } - - render () { - return ( -
    - {this.state.users.map((user) => ( -
  • - {user.id} - {user.name} -
  • - ))} -
    - ) - } -} diff --git a/npm/react/cypress/component/advanced/renderless/mouse-movement.jsx b/npm/react/cypress/component/advanced/renderless/mouse-movement.jsx index 8e838c58b208..609337969ec5 100644 --- a/npm/react/cypress/component/advanced/renderless/mouse-movement.jsx +++ b/npm/react/cypress/component/advanced/renderless/mouse-movement.jsx @@ -1,52 +1,44 @@ // https://medium.com/@pierrehedkvist/renderless-components-in-react-8d663746314c -import React from 'react' +// eslint-disable-next-line no-unused-vars +import React, { useState, useEffect } from 'react' import PropTypes from 'prop-types' -export default class MouseMovement extends React.Component { - constructor (props) { - console.log('MouseMovement constructor') - super(props) - this.state = { - timer: undefined, - } - - this.timeout = this.timeout.bind(this) - this.onMouseMove = this.onMouseMove.bind(this) - } +export default function MouseMovement ({ onMoved }) { + const [timer, setTimer] = useState(undefined) - componentWillMount () { - console.log('MouseMovement componentWillMount') - document.addEventListener('mousemove', this.onMouseMove) - const timer = setTimeout(this.timeout, 4000) + function onMouseMove () { + console.log('MouseMovement onMouseMove') + clearTimeout(timer) + const timerNew = setTimeout(timeout, 4000) - this.setState({ timer }) + setTimer(timerNew) + onMoved(true) } - componentWillUnmount () { - console.log('MouseMovement componentWillUnmount') - document.removeEventListener('mousemove', this.onMouseMove) - clearTimeout(this.state.timer) - this.setState({ timer: undefined }) + function timeout () { + console.log('timeout') + clearTimeout(timer) + onMoved(false) } - onMouseMove () { - console.log('MouseMovement onMouseMove') - clearTimeout(this.state.timer) - const timer = setTimeout(this.timeout, 4000) + useEffect(() => { + // Anything in here is fired on component mount. + console.log('MouseMovement componentWillMount') + document.addEventListener('mousemove', onMouseMove) + const timerNew = setTimeout(timeout, 4000) - this.setState({ timer }) - this.props.onMoved(true) - } + setTimer(timerNew) - timeout () { - console.log('timeout') - clearTimeout(this.state.timer) - this.props.onMoved(false) - } + return () => { + // Anything in here is fired on component unmount. + console.log('MouseMovement componentWillUnmount') + document.removeEventListener('mousemove', onMouseMove) + clearTimeout(timer) + setTimer(undefined) + } + }) - render () { - return null - } + return null } MouseMovement.propTypes = { diff --git a/npm/react/cypress/component/advanced/renderless/mouse.cy.jsx b/npm/react/cypress/component/advanced/renderless/mouse.cy.jsx index 670d3dc92214..4bd6984dac03 100644 --- a/npm/react/cypress/component/advanced/renderless/mouse.cy.jsx +++ b/npm/react/cypress/component/advanced/renderless/mouse.cy.jsx @@ -5,14 +5,6 @@ import MouseMovement from './mouse-movement' describe('Renderless component', () => { it('works', () => { - // let's also spy on "console.log" calls - // to make sure the entire sequence of calls happens - cy.window() - .its('console') - .then((console) => { - cy.spy(console, 'log').as('log') - }) - const onMoved = cy.stub() mount() @@ -23,27 +15,7 @@ describe('Renderless component', () => { expect(onMoved).to.have.been.calledWith(true) }) - // mount something else to trigger unmount + // mount something else to trigger unmount and stop log flow mount(
    Test Component
    ) - - cy.get('@log') - .its('callCount') - .should('equal', 4) - - cy.get('@log') - .invoke('getCalls') - .then((calls) => { - return calls.map((call) => { - console.log('one', call.args[0]) - - return call.args[0] - }) - }) - .should('deep.equal', [ - 'MouseMovement constructor', - 'MouseMovement componentWillMount', - 'MouseMovement onMouseMove', - 'MouseMovement componentWillUnmount', - ]) }) }) diff --git a/npm/react/cypress/component/advanced/set-timeout-example/App.jsx b/npm/react/cypress/component/advanced/set-timeout-example/App.jsx index 6c4aa515a9a0..6346e91ba177 100644 --- a/npm/react/cypress/component/advanced/set-timeout-example/App.jsx +++ b/npm/react/cypress/component/advanced/set-timeout-example/App.jsx @@ -1,35 +1,31 @@ -import React, { Component } from 'react' +import React, { useState, useEffect } from 'react' import './App.css' import logo from './logo.svg' import LoadingIndicator from './LoadingIndicator' -class App extends Component { - state = { - isLoading: true, - } +function App () { + const [isLoading, setIsLoading] = useState(true) - componentDidMount () { - this._timer = setTimeout(() => this.setState({ isLoading: false }), 2000) - } + useEffect(() => { + const _timer = setTimeout(() => setIsLoading(false), 2000) - componentWillUnmount () { - clearTimeout(this._timer) - } + return () => { + clearTimeout(_timer) + } + }) - render () { - return ( -
    -
    - logo -

    Welcome to React

    -
    -
    isLoading: {String(this.state.isLoading)}
    - -
    ahoy!
    -
    -
    - ) - } + return ( +
    +
    + logo +

    Welcome to React

    +
    +
    isLoading: {String(isLoading)}
    + +
    ahoy!
    +
    +
    + ) } export default App diff --git a/npm/react/cypress/component/advanced/set-timeout-example/LoadingIndicator.jsx b/npm/react/cypress/component/advanced/set-timeout-example/LoadingIndicator.jsx index 0c6cdfec36dc..b5efe7a250d9 100644 --- a/npm/react/cypress/component/advanced/set-timeout-example/LoadingIndicator.jsx +++ b/npm/react/cypress/component/advanced/set-timeout-example/LoadingIndicator.jsx @@ -1,37 +1,26 @@ -import React, { Component } from 'react' -import PropTypes from 'prop-types' +import React, { useState, useEffect } from 'react' -export default class LoadingIndicator extends Component { - static propTypes = { - isLoading: PropTypes.bool.isRequired, - } - - state = { - isPastDelay: false, - } +export default function LoadingIndicator ({ isLoading, children }) { + const [isPastDelay, setIsPastDelay] = useState(false) - componentDidMount () { - console.log('component did mount') - this._delayTimer = setTimeout(() => { + useEffect(() => { + const _delayTimer = setTimeout(() => { console.log('2000ms passed') - this.setState({ isPastDelay: true }) + setIsPastDelay(true) }, 2000) - } - componentWillUnmount () { - console.log('componentWillUnmount') - clearTimeout(this._delayTimer) - } - - render () { - if (this.props.isLoading) { - if (!this.state.isPastDelay) { - return null - } + return () => { + clearTimeout(_delayTimer) + } + }) - return
    loading...
    + if (isLoading) { + if (!isPastDelay) { + return null } - return this.props.children + return
    loading...
    } + + return children } diff --git a/npm/react/cypress/component/advanced/timers/card-without-effect.jsx b/npm/react/cypress/component/advanced/timers/card-without-effect.jsx index e85bc2ef301d..e1b40c692353 100644 --- a/npm/react/cypress/component/advanced/timers/card-without-effect.jsx +++ b/npm/react/cypress/component/advanced/timers/card-without-effect.jsx @@ -1,5 +1,6 @@ import React, { Component } from 'react' +// Class components will be removed in a future release of React 18+. Until then, this example will serve as a class component example export default class Card extends Component { componentDidMount () { this._timeoutID = setTimeout(() => { diff --git a/npm/react/cypress/component/advanced/tutorial/shopping-list.jsx b/npm/react/cypress/component/advanced/tutorial/shopping-list.jsx index b2ea82ee7b94..7dec846617b5 100644 --- a/npm/react/cypress/component/advanced/tutorial/shopping-list.jsx +++ b/npm/react/cypress/component/advanced/tutorial/shopping-list.jsx @@ -1,16 +1,14 @@ import React from 'react' -export default class ShoppingList extends React.Component { - render () { - return ( -
    -

    Shopping List for {this.props.name}

    -
      -
    • Instagram
    • -
    • WhatsApp
    • -
    • Oculus
    • -
    -
    - ) - } +export default function ShoppingList ({ name }) { + return ( +
    +

    Shopping List for {name}

    +
      +
    • Instagram
    • +
    • WhatsApp
    • +
    • Oculus
    • +
    +
    + ) } diff --git a/npm/react/cypress/component/advanced/tutorial/square.cy.jsx b/npm/react/cypress/component/advanced/tutorial/square.cy.jsx index 33e70df52aaf..57aaa5a3d17c 100644 --- a/npm/react/cypress/component/advanced/tutorial/square.cy.jsx +++ b/npm/react/cypress/component/advanced/tutorial/square.cy.jsx @@ -1,27 +1,17 @@ /// -import React from 'react' +import React, { useState } from 'react' import { mount } from '@cypress/react' import './tic-tac-toe.css' // let's put React component right in the spec file -class Square extends React.Component { - constructor (props) { - super(props) - this.state = { - value: null, - } - } +export default function Square ({ value: valueAsProp }) { + const [valueAsState, setValueAsState] = useState(null) - render () { - return ( - - ) - } + return ( + + ) } describe('Square', () => { diff --git a/npm/react/cypress/component/advanced/tutorial/tic-tac-toe.cy.jsx b/npm/react/cypress/component/advanced/tutorial/tic-tac-toe.cy.jsx index c4b93f89803c..57bfea3cc867 100644 --- a/npm/react/cypress/component/advanced/tutorial/tic-tac-toe.cy.jsx +++ b/npm/react/cypress/component/advanced/tutorial/tic-tac-toe.cy.jsx @@ -3,7 +3,7 @@ /// import React from 'react' import { mount } from '@cypress/react' -import { Game } from './tic-tac-toe.jsx' +import Game from './tic-tac-toe.jsx' import './tic-tac-toe.css' describe('Tic Tac Toe', () => { diff --git a/npm/react/cypress/component/advanced/tutorial/tic-tac-toe.jsx b/npm/react/cypress/component/advanced/tutorial/tic-tac-toe.jsx index 35c4a704c017..b7b0f2f76013 100644 --- a/npm/react/cypress/component/advanced/tutorial/tic-tac-toe.jsx +++ b/npm/react/cypress/component/advanced/tutorial/tic-tac-toe.jsx @@ -1,115 +1,125 @@ -// entire game from the tutorial inside the spec for simplicity -// the code taken from https://codepen.io/gaearon/pen/LyyXgK -import React from 'react' +import React, { useState } from 'react' -export function calculateWinner (squares) { - const lines = [ - [0, 1, 2], - [3, 4, 5], - [6, 7, 8], - [0, 3, 6], - [1, 4, 7], - [2, 5, 8], - [0, 4, 8], - [2, 4, 6], - ] +function Square ({ value, onSquareClick }) { + return ( + + ) +} - for (let i = 0; i < lines.length; i++) { - const [a, b, c] = lines[i] +export function Board ({ xIsNext, squares, onPlay }) { + function handleClick (i) { + if (calculateWinner(squares) || squares[i]) { + return + } - if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) { - return squares[a] + const nextSquares = squares.slice() + + if (xIsNext) { + nextSquares[i] = 'X' + } else { + nextSquares[i] = 'O' } + + onPlay(nextSquares) } - return null -} + const winner = calculateWinner(squares) + let status + + if (winner) { + status = `Winner: ${ winner}` + } else { + status = `Next player: ${ xIsNext ? 'X' : 'O'}` + } -function Square (props) { return ( - + <> +
    {status}
    +
    + handleClick(0)} /> + handleClick(1)} /> + handleClick(2)} /> +
    +
    + handleClick(3)} /> + handleClick(4)} /> + handleClick(5)} /> +
    +
    + handleClick(6)} /> + handleClick(7)} /> + handleClick(8)} /> +
    + ) } -export class Board extends React.Component { - constructor (props) { - super(props) - this.state = { - squares: Array(9).fill(null), - xIsNext: true, - } - } +export default function Game () { + const [history, setHistory] = useState([Array(9).fill(null)]) + const [currentMove, setCurrentMove] = useState(0) + const xIsNext = currentMove % 2 === 0 + const currentSquares = history[currentMove] - handleClick (i) { - const squares = this.state.squares.slice() + function handlePlay (nextSquares) { + const nextHistory = [...history.slice(0, currentMove + 1), nextSquares] - if (calculateWinner(squares) || squares[i]) { - return - } - - squares[i] = this.state.xIsNext ? 'X' : 'O' - this.setState({ - squares, - xIsNext: !this.state.xIsNext, - }) + setHistory(nextHistory) + setCurrentMove(nextHistory.length - 1) } - renderSquare (i) { - return ( - this.handleClick(i)} - /> - ) + function jumpTo (nextMove) { + setCurrentMove(nextMove) } - render () { - const winner = calculateWinner(this.state.squares) - let status + const moves = history.map((squares, move) => { + let description - if (winner) { - status = `Winner: ${winner}` + if (move > 0) { + description = `Go to move #${ move}` } else { - status = `Next player: ${this.state.xIsNext ? 'X' : 'O'}` + description = 'Go to game start' } return ( -
    -
    {status}
    -
    - {this.renderSquare(0)} - {this.renderSquare(1)} - {this.renderSquare(2)} -
    -
    - {this.renderSquare(3)} - {this.renderSquare(4)} - {this.renderSquare(5)} -
    -
    - {this.renderSquare(6)} - {this.renderSquare(7)} - {this.renderSquare(8)} -
    -
    +
  • + +
  • ) - } -} + }) -export class Game extends React.Component { - render () { - return ( -
    -
    - -
    -
    -
    {/* status */}
    -
      {/* TODO */}
    -
    + return ( +
    +
    +
    - ) +
    +
      {moves}
    +
    +
    + ) +} + +export function calculateWinner (squares) { + const lines = [ + [0, 1, 2], + [3, 4, 5], + [6, 7, 8], + [0, 3, 6], + [1, 4, 7], + [2, 5, 8], + [0, 4, 8], + [2, 4, 6], + ] + + for (let i = 0; i < lines.length; i++) { + const [a, b, c] = lines[i] + + if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) { + return squares[a] + } } + + return null } diff --git a/npm/react/cypress/component/basic/css/Button.jsx b/npm/react/cypress/component/basic/css/Button.jsx index f2801f5dc218..69564bb12127 100644 --- a/npm/react/cypress/component/basic/css/Button.jsx +++ b/npm/react/cypress/component/basic/css/Button.jsx @@ -1,22 +1,20 @@ import React from 'react' import './Button.css' -export class Button extends React.Component { - handleClick () { - this.props.clickHandler(this.props.name) - } - - render () { - const className = [ - 'component-button', - this.props.orange ? 'orange' : '', - this.props.wide ? 'wide' : '', - ] +export function Button ({ name, orange, wide, clickHandler }) { + const className = [ + 'component-button', + orange ? 'orange' : '', + wide ? 'wide' : '', + ] - return ( -
    - -
    - ) + function handleClick () { + clickHandler(name) } + + return ( +
    + +
    + ) } diff --git a/npm/react/cypress/component/basic/enzyme/README.md b/npm/react/cypress/component/basic/enzyme/README.md deleted file mode 100644 index 947f0b442ed8..000000000000 --- a/npm/react/cypress/component/basic/enzyme/README.md +++ /dev/null @@ -1,98 +0,0 @@ -# Enzyme examples - -This folder shows several examples from [Enzyme docs](https://enzymejs.github.io/enzyme/). - -In general if you are migrating from Enzyme to `@cypress/react`: - -- there is no shallow mounting, only the full mounting. Thus `@cypress/react` has `mount` which is similar to the Enzyme's `render`. It renders the full HTML and CSS output of your component. -- you can mock [children components](https://github.com/bahmutov/cypress-react-unit-test/tree/main/cypress/component/advanced/mocking-component) if you want to avoid running "expensive" components during tests -- the test is running as a "mini" web application. Thus if you want to set a context around component, then set the [context around the component](https://github.com/bahmutov/cypress-react-unit-test/tree/main/cypress/component/advanced/context) - -## setState - -If you want to change the component's internal state, use the component reference. You can get it by using the special property `ref` when mounting. - -```js -// get the component reference using "ref" prop -// and place it into the object for Cypress to "wait" for it -let c = {} -mount( (c.instance = i)} />) -cy.wrap(c) - .its('instance') - .invoke('setState', { count: 10 }) -``` - -See [state-spec.js](state-spec.js) file. - -## setProps - -There is no direct implementation of `setProps`. If you want to see how the component behaves with different props: - -```js -it('mounts component with new props', () => { - mount() - cy.contains('initial').should('be.visible') - - mount() - cy.contains('second').should('be.visible') -}) -``` - -If you want to reuse properties, you can even clone the component - -```js -it('mounts cloned component', () => { - const cmp = - mount(cmp) - cy.contains('initial').should('be.visible') - - const cloned = Cypress._.cloneDeep(cmp) - // change a property, leaving the rest unchanged - cloned.props.foo = 'second' - mount(cloned) - cy.contains('.foo', 'second').should('be.visible') -}) -``` - -See [props-spec.js](props-spec.js) file. - -## context - -Enzyme's `mount` method allows passing the [React context](https://reactjs.org/docs/context.html) as the second argument to the JSX component like `SimpleComponent` below. - -```js -function SimpleComponent(props, context) { - const { name } = context - return
    {name || 'not set'}
    -} -``` - -Since the above syntax is [deprecated](https://reactjs.org/docs/legacy-context.html), `@cypress/react` does not support it. Instead use `createContext` and `Context.Provider` to surround the mounted component, just like you would do in a regular application code. - -```js -mount( - - - , -) -``` - -Instead of setting a new context, mount the same component but surround it with a different context provider - -```js -const cmp = -mount( - - {cmp} - , -) - -// same component, different provider -mount( - - {cmp} - , -) -``` - -See [context-spec.js](context-spec.js) for more examples. diff --git a/npm/react/cypress/component/basic/enzyme/context.cy.jsx b/npm/react/cypress/component/basic/enzyme/context.cy.jsx deleted file mode 100644 index 87e660cab7af..000000000000 --- a/npm/react/cypress/component/basic/enzyme/context.cy.jsx +++ /dev/null @@ -1,53 +0,0 @@ -/// -import React from 'react' -import { mount } from '@cypress/react' -import { SimpleContext } from './simple-context' -import { SimpleComponent } from './simple-component.jsx' - -// testing components that use Context React API -// https://reactjs.org/docs/context.html -describe('Enzyme', () => { - context('setContext', () => { - it('does not provide the context', () => { - mount() - cy.contains('context not set').should('be.visible') - }) - - it('provides the context', () => { - // surround the component with the real provider but - // set the value prop to whatever the test requires - mount( - - - , - ) - - cy.contains('test context').should('be.visible') - }) - - it('mounts new context', () => { - // instead of setting the context from the test - // just mount the component again with a different provider around it - const cmp = - - mount( - - {cmp} - , - ) - - cy.contains('first context').should('be.visible') - cy.contains('.id', '0x123').should('be.visible') - - // same component, different provider - mount( - - {cmp} - , - ) - - cy.contains('second context').should('be.visible') - cy.contains('.id', '0x123').should('be.visible') - }) - }) -}) diff --git a/npm/react/cypress/component/basic/enzyme/props.cy.jsx b/npm/react/cypress/component/basic/enzyme/props.cy.jsx deleted file mode 100644 index 0ccb58844c06..000000000000 --- a/npm/react/cypress/component/basic/enzyme/props.cy.jsx +++ /dev/null @@ -1,82 +0,0 @@ -/// -import React from 'react' -import { mount } from '@cypress/react' - -class Foo extends React.Component { - constructor (props) { - super(props) - - this.state = { - count: 0, - } - } - - componentDidMount () { - console.log('componentDidMount called') - } - - componentDidUpdate () { - console.log('componentDidUpdate called') - } - - render () { - const { id, foo } = this.props - - return ( -
    - {foo} count {this.state.count} -
    - ) - } -} - -describe('Enzyme', () => { - // example test copied from - // https://github.com/enzymejs/enzyme/blob/master/packages/enzyme-test-suite/test/shared/methods/setProps.jsx - - context('setProps', () => { - it('gets props from the component', () => { - mount().as('Foo') - cy.contains('initial').should('be.visible') - - cy.get('@Foo') - .its('component') - .its('props') - .then((props) => { - console.log('current props', props) - expect(props).to.deep.equal({ - id: 'foo', - foo: 'initial', - }) - - // you can get current props of the component - // but not change them - they are read-only - expect(() => { - props.foo = 'change 1' - }).to.throw() - }) - }) - - it('mounts component with new props', () => { - mount() - cy.contains('initial').should('be.visible') - - mount() - cy.contains('second').should('be.visible') - }) - - it('mounts cloned component', () => { - const cmp = - - mount(cmp) - cy.contains('initial').should('be.visible') - - const cloned = Cypress._.cloneDeep(cmp) - - // change a property, leaving the rest unchanged - cloned.props.foo = 'second' - mount(cloned) - cy.contains('.foo', 'second').should('be.visible') - }) - }) -}) diff --git a/npm/react/cypress/component/basic/enzyme/simple-component.jsx b/npm/react/cypress/component/basic/enzyme/simple-component.jsx deleted file mode 100644 index 57eacb77b2f8..000000000000 --- a/npm/react/cypress/component/basic/enzyme/simple-component.jsx +++ /dev/null @@ -1,24 +0,0 @@ -import React from 'react' -import { SimpleContext } from './simple-context' - -export class SimpleComponent extends React.Component { - constructor (props) { - super(props) - this.state = { - id: props.id || 'unknown id', - } - } - - render () { - console.log('context %o', this.context) - - return ( - <> -
    {this.context.name || 'context not set'}
    -
    {this.state.id}
    - - ) - } -} - -SimpleComponent.contextType = SimpleContext diff --git a/npm/react/cypress/component/basic/enzyme/simple-context.jsx b/npm/react/cypress/component/basic/enzyme/simple-context.jsx deleted file mode 100644 index 80fd038f2e82..000000000000 --- a/npm/react/cypress/component/basic/enzyme/simple-context.jsx +++ /dev/null @@ -1,4 +0,0 @@ -// https://reactjs.org/docs/context.html -import { createContext } from 'react' - -export const SimpleContext = createContext({ name: '' }) diff --git a/npm/react/cypress/component/basic/enzyme/state.cy.jsx b/npm/react/cypress/component/basic/enzyme/state.cy.jsx deleted file mode 100644 index 2f3db3157097..000000000000 --- a/npm/react/cypress/component/basic/enzyme/state.cy.jsx +++ /dev/null @@ -1,60 +0,0 @@ -/// -import React from 'react' -import { mount } from '@cypress/react' - -class Foo extends React.Component { - constructor (props) { - super(props) - - this.state = { - count: 0, - } - } - - componentDidMount () { - console.log('componentDidMount called') - } - - componentDidUpdate () { - console.log('componentDidUpdate called') - } - - render () { - const { id, foo } = this.props - - return ( -
    - {foo} count {this.state.count} -
    - ) - } -} - -describe('Enzyme', () => { - context('setState', () => { - it('sets component state', () => { - // get the component reference using "ref" prop - // and place it into the object for Cypress to "wait" for it - let c = {} - - mount( (c.instance = i)} />) - cy.contains('initial').should('be.visible') - - cy.log('**check state**') - cy.wrap(c) - .its('instance.state') - .should('deep.equal', { count: 0 }) - - cy.log('**setState**') - cy.wrap(c) - .its('instance') - .invoke('setState', { count: 10 }) - - cy.wrap(c) - .its('instance.state') - .should('deep.equal', { count: 10 }) - - cy.contains('initial count 10') - }) - }) -}) diff --git a/npm/react/cypress/component/basic/network/1-users.jsx b/npm/react/cypress/component/basic/network/1-users.jsx index 6f879c6f6337..feb0aafacfdb 100644 --- a/npm/react/cypress/component/basic/network/1-users.jsx +++ b/npm/react/cypress/component/basic/network/1-users.jsx @@ -1,34 +1,26 @@ -import React from 'react' +import React, { useState, useEffect } from 'react' import axios from 'axios' -export class Users extends React.Component { - constructor (props) { - super(props) - this.state = { - users: [], - } - } +export function Users () { + const [users, setUsers] = useState([]) - componentDidMount () { - axios - .get('https://jsonplaceholder.cypress.io/users?_limit=3') - .then((response) => { - // JSON responses are automatically parsed. - this.setState({ - users: response.data, - }) - }) - } + const getUsers = async () => { + const response = await axios.get('https://jsonplaceholder.cypress.io/users?_limit=3') - render () { - return ( -
    - {this.state.users.map((user) => ( -
  • - {user.id} - {user.name} -
  • - ))} -
    - ) + setUsers(response.data) } + + useEffect(() => { + getUsers() + }, []) + + return ( +
    + {users.map((user) => ( +
  • + {user.id} - {user.name} +
  • + ))} +
    + ) } diff --git a/npm/react/cypress/component/basic/network/2-users-fetch.jsx b/npm/react/cypress/component/basic/network/2-users-fetch.jsx index f63f26c53254..b5d302291010 100644 --- a/npm/react/cypress/component/basic/network/2-users-fetch.jsx +++ b/npm/react/cypress/component/basic/network/2-users-fetch.jsx @@ -1,34 +1,26 @@ -import React from 'react' +import React, { useState, useEffect } from 'react' -export class Users extends React.Component { - constructor (props) { - super(props) - this.state = { - users: [], - } - } +export function Users () { + const [users, setUsers] = useState([]) - componentDidMount () { - fetch('https://jsonplaceholder.cypress.io/users?_limit=3') - .then((response) => { - return response.json() - }) - .then((list) => { - this.setState({ - users: list, - }) - }) - } + const getUsers = async () => { + const response = await fetch('https://jsonplaceholder.cypress.io/users?_limit=3') + const list = await response.json() - render () { - return ( -
    - {this.state.users.map((user) => ( -
  • - {user.id} - {user.name} -
  • - ))} -
    - ) + setUsers(list) } + + useEffect(() => { + getUsers() + }, []) + + return ( +
    + {users.map((user) => ( +
  • + {user.id} - {user.name} +
  • + ))} +
    + ) } diff --git a/npm/react/cypress/component/basic/react-tutorial/game.cy.jsx b/npm/react/cypress/component/basic/react-tutorial/game.cy.jsx index c365c60638c0..263c638db5c0 100644 --- a/npm/react/cypress/component/basic/react-tutorial/game.cy.jsx +++ b/npm/react/cypress/component/basic/react-tutorial/game.cy.jsx @@ -5,11 +5,11 @@ import { mount } from '@cypress/react' import './tic-tac-toe.css' // for now need a constructor, otherwise getting "Weak map" key -const BoardWrap = ({ squares, onClick }) => { +const BoardWrap = ({ squares, onPlay }) => { return (
    - +
    ) @@ -21,16 +21,16 @@ beforeEach(() => { it('renders empty Board', () => { const squares = Array(9).fill(null) - const onClick = cy.stub() + const onPlay = cy.stub() - mount() + mount() cy.get('.board-row') .eq(0) .find('.square') .eq(0) .click() .then(() => { - expect(onClick).to.have.been.calledWith(0) + expect(onPlay).to.have.been.called }) }) @@ -55,7 +55,7 @@ it('renders Board with a few squares filled', () => { it('plays the game', () => { mount() - cy.contains('.game-info', 'Next player: X').should('be.visible') + cy.contains('.game-board > .status', 'Next player: X').should('be.visible') cy.get('.board-row') .eq(0) .find('.square') @@ -87,7 +87,7 @@ it('plays the game', () => { .eq(2) .click() - cy.contains('.game-info', 'Winner: X').should('be.visible') + cy.contains('.game-board > .status', 'Winner: X').should('be.visible') // history of moves cy.get('ol li') .should('have.length', 6) diff --git a/npm/react/cypress/component/basic/react-tutorial/game.jsx b/npm/react/cypress/component/basic/react-tutorial/game.jsx index 65f9f6c12b74..b7b0f2f76013 100644 --- a/npm/react/cypress/component/basic/react-tutorial/game.jsx +++ b/npm/react/cypress/component/basic/react-tutorial/game.jsx @@ -1,129 +1,105 @@ -// from https://codepen.io/gaearon/pen/gWWZgR -import React from 'react' +import React, { useState } from 'react' -function Square (props) { +function Square ({ value, onSquareClick }) { return ( - ) } -export class Board extends React.Component { - renderSquare (i) { - return ( - this.props.onClick(i)} - /> - ) - } - - render () { - return ( -
    -
    - {this.renderSquare(0)} - {this.renderSquare(1)} - {this.renderSquare(2)} -
    -
    - {this.renderSquare(3)} - {this.renderSquare(4)} - {this.renderSquare(5)} -
    -
    - {this.renderSquare(6)} - {this.renderSquare(7)} - {this.renderSquare(8)} -
    -
    - ) - } -} - -export default class Game extends React.Component { - constructor (props) { - super(props) - this.state = { - history: [ - { - squares: Array(9).fill(null), - }, - ], - stepNumber: 0, - xIsNext: true, +export function Board ({ xIsNext, squares, onPlay }) { + function handleClick (i) { + if (calculateWinner(squares) || squares[i]) { + return } - } - handleClick (i) { - const history = this.state.history.slice(0, this.state.stepNumber + 1) - const current = history[history.length - 1] - const squares = current.squares.slice() + const nextSquares = squares.slice() - if (calculateWinner(squares) || squares[i]) { - return + if (xIsNext) { + nextSquares[i] = 'X' + } else { + nextSquares[i] = 'O' } - squares[i] = this.state.xIsNext ? 'X' : 'O' - this.setState({ - history: history.concat([ - { - squares, - }, - ]), - stepNumber: history.length, - xIsNext: !this.state.xIsNext, - }) + onPlay(nextSquares) } - jumpTo (step) { - this.setState({ - stepNumber: step, - xIsNext: step % 2 === 0, - }) + const winner = calculateWinner(squares) + let status + + if (winner) { + status = `Winner: ${ winner}` + } else { + status = `Next player: ${ xIsNext ? 'X' : 'O'}` } - render () { - const history = this.state.history - const current = history[this.state.stepNumber] - const winner = calculateWinner(current.squares) + return ( + <> +
    {status}
    +
    + handleClick(0)} /> + handleClick(1)} /> + handleClick(2)} /> +
    +
    + handleClick(3)} /> + handleClick(4)} /> + handleClick(5)} /> +
    +
    + handleClick(6)} /> + handleClick(7)} /> + handleClick(8)} /> +
    + + ) +} + +export default function Game () { + const [history, setHistory] = useState([Array(9).fill(null)]) + const [currentMove, setCurrentMove] = useState(0) + const xIsNext = currentMove % 2 === 0 + const currentSquares = history[currentMove] + + function handlePlay (nextSquares) { + const nextHistory = [...history.slice(0, currentMove + 1), nextSquares] - const moves = history.map((step, move) => { - const desc = move ? `Go to move #${move}` : 'Go to game start' + setHistory(nextHistory) + setCurrentMove(nextHistory.length - 1) + } - return ( -
  • - -
  • - ) - }) + function jumpTo (nextMove) { + setCurrentMove(nextMove) + } - let status + const moves = history.map((squares, move) => { + let description - if (winner) { - status = `Winner: ${winner}` + if (move > 0) { + description = `Go to move #${ move}` } else { - status = `Next player: ${this.state.xIsNext ? 'X' : 'O'}` + description = 'Go to game start' } return ( -
    -
    - this.handleClick(i)} /> -
    -
    -
    {status}
    -
      {moves}
    -
    -
    +
  • + +
  • ) - } -} + }) -// ======================================== - -// ReactDOM.render(, document.getElementById('root')) + return ( +
    +
    + +
    +
    +
      {moves}
    +
    +
    + ) +} export function calculateWinner (squares) { const lines = [ diff --git a/npm/react/cypress/component/basic/react-tutorial/shopping-list.jsx b/npm/react/cypress/component/basic/react-tutorial/shopping-list.jsx index 5d922a6b122b..8b117f38cfeb 100644 --- a/npm/react/cypress/component/basic/react-tutorial/shopping-list.jsx +++ b/npm/react/cypress/component/basic/react-tutorial/shopping-list.jsx @@ -1,18 +1,16 @@ import React from 'react' -export default class ShoppingList extends React.Component { - render () { - return ( -
    -

    Shopping List for {this.props.name}

    -
      -
    • Instagram
    • -
    • WhatsApp
    • -
    • Oculus
    • -
    -
    - ) - } +export default function ShoppingList ({ name }) { + return ( +
    +

    Shopping List for {name}

    +
      +
    • Instagram
    • +
    • WhatsApp
    • +
    • Oculus
    • +
    +
    + ) } // Example usage: diff --git a/npm/react/cypress/component/basic/react-tutorial/square1.jsx b/npm/react/cypress/component/basic/react-tutorial/square1.jsx index c2ca98ddd64b..60bde2cb49a6 100644 --- a/npm/react/cypress/component/basic/react-tutorial/square1.jsx +++ b/npm/react/cypress/component/basic/react-tutorial/square1.jsx @@ -1,11 +1,9 @@ import React from 'react' -export default class Square extends React.Component { - render () { - return ( - - ) - } +export default function Square ({ value }) { + return ( + + ) } diff --git a/npm/react/cypress/component/basic/react-tutorial/square2.jsx b/npm/react/cypress/component/basic/react-tutorial/square2.jsx index 564fd505c3de..9869d3ef332b 100644 --- a/npm/react/cypress/component/basic/react-tutorial/square2.jsx +++ b/npm/react/cypress/component/basic/react-tutorial/square2.jsx @@ -1,18 +1,9 @@ import React from 'react' -export default class Square extends React.Component { - constructor (props) { - super(props) - this.state = { - value: null, - } - } - - render () { - return ( - - ) - } +export default function Square ({ value }) { + return ( + + ) } diff --git a/npm/react/cypress/component/basic/react-tutorial/square3.jsx b/npm/react/cypress/component/basic/react-tutorial/square3.jsx index 35bc02beee2f..1c5122962847 100644 --- a/npm/react/cypress/component/basic/react-tutorial/square3.jsx +++ b/npm/react/cypress/component/basic/react-tutorial/square3.jsx @@ -1,18 +1,11 @@ -import React from 'react' +import React, { useState } from 'react' -export default class Square extends React.Component { - constructor (props) { - super(props) - this.state = { - value: null, - } - } +export default function Square () { + const [value, setValue] = useState(null) - render () { - return ( - - ) - } + return ( + + ) } diff --git a/npm/react/cypress/component/basic/react-tutorial/square4.jsx b/npm/react/cypress/component/basic/react-tutorial/square4.jsx index 507259650fa1..97ee0aaed834 100644 --- a/npm/react/cypress/component/basic/react-tutorial/square4.jsx +++ b/npm/react/cypress/component/basic/react-tutorial/square4.jsx @@ -1,9 +1,9 @@ import React from 'react' -export default function Square (props) { +export default function Square ({ value, onClick }) { return ( - ) } diff --git a/npm/react/cypress/component/basic/rerender/effects.cy.jsx b/npm/react/cypress/component/basic/rerender/effects.cy.jsx index cebe663c7e08..b170d0ad6b9c 100644 --- a/npm/react/cypress/component/basic/rerender/effects.cy.jsx +++ b/npm/react/cypress/component/basic/rerender/effects.cy.jsx @@ -1,7 +1,6 @@ /// import React, { useLayoutEffect, useEffect } from 'react' -import ReactDom from 'react-dom' -import { mount, getContainerEl } from '@cypress/react' +import { mount } from '@cypress/react' it('should not run unmount effect cleanup when rerendering', () => { const layoutEffectCleanup = cy.stub() @@ -60,8 +59,8 @@ it('should run unmount effect cleanup when unmounting', () => { expect(effectCleanup).to.have.been.callCount(0) }) - cy - .then(() => ReactDom.unmountComponentAtNode(getContainerEl())) + // mount something else to trigger an unmount event + cy.mount(
    Hello
    ) .then(async () => { // does not call useEffect in react 17 unmount synchronously. // @see https://github.com/facebook/react/issues/20263 diff --git a/npm/react/cypress/component/basic/unmount/comp.cy.jsx b/npm/react/cypress/component/basic/unmount/comp.cy.jsx index f12b80c56e6c..c6f53a307379 100644 --- a/npm/react/cypress/component/basic/unmount/comp.cy.jsx +++ b/npm/react/cypress/component/basic/unmount/comp.cy.jsx @@ -1,5 +1,5 @@ /// -import Comp from './comp.jsx' +import { Comp } from './comp.jsx' import React from 'react' import { mount, unmount } from '@cypress/react' @@ -11,7 +11,6 @@ it('calls callbacks on mount and unmount', () => { mount() cy.then(() => { expect(onMount).to.have.been.calledOnce - expect(onUnmount).to.have.not.been.called }) cy.contains('Component with').should('be.visible') diff --git a/npm/react/cypress/component/basic/unmount/comp.jsx b/npm/react/cypress/component/basic/unmount/comp.jsx index 25122014f86f..0cdb87524b58 100644 --- a/npm/react/cypress/component/basic/unmount/comp.jsx +++ b/npm/react/cypress/component/basic/unmount/comp.jsx @@ -1,15 +1,9 @@ -import React, { Component } from 'react' +import React, { useEffect } from 'react' -export default class Comp extends Component { - componentDidMount () { - this.props.onMount() - } +export const Comp = ({ onMount }) => { + useEffect(() => { + onMount() + }, []) - componentWillUnmount () { - this.props.onUnmount() - } - - render () { - return
    Component with mount and unmount calls
    - } + return
    Component with mount and unmount calls
    } diff --git a/npm/react/cypress/component/basic/unmount/unmount.cy.jsx b/npm/react/cypress/component/basic/unmount/unmount.cy.jsx deleted file mode 100644 index e4bd608e723e..000000000000 --- a/npm/react/cypress/component/basic/unmount/unmount.cy.jsx +++ /dev/null @@ -1,45 +0,0 @@ -/// -import React, { Component } from 'react' -import { getContainerEl } from '@cypress/mount-utils' -import ReactDom from 'react-dom' -import { mount } from '@cypress/react' - -class Comp extends Component { - componentWillUnmount () { - // simply calls the prop - this.props.onUnmount() - } - - render () { - return
    My component
    - } -} - -describe('Comp with componentWillUnmount', () => { - it('calls the prop', () => { - mount() - cy.contains('My component') - - // after we have confirmed the component exists let's remove it - // unmount() command is automatically enqueued - cy.then(() => ReactDom.unmountComponentAtNode(getContainerEl())) - - // the component is gone from the DOM - cy.contains('My component').should('not.exist') - // the component has called the prop on unmount - cy.get('@onUnmount').should('have.been.calledOnce') - }) - - it('can be called using then', () => { - mount() - cy.contains('My component') - - // still works, should probably be removed in v5 - cy.then(() => ReactDom.unmountComponentAtNode(getContainerEl())) - - // the component is gone from the DOM - cy.contains('My component').should('not.exist') - // the component has called the prop on unmount - cy.get('@onUnmount').should('have.been.calledOnce') - }) -}) diff --git a/npm/react/cypress/component/basic/use-render/my-component.jsx b/npm/react/cypress/component/basic/use-render/my-component.jsx index 76a66262e66a..5fd5db9c3180 100644 --- a/npm/react/cypress/component/basic/use-render/my-component.jsx +++ b/npm/react/cypress/component/basic/use-render/my-component.jsx @@ -1,10 +1,7 @@ import React from 'react' -class MyComponent extends React.Component { - state = {} - render () { - return
    Hello
    - } +export function MyComponent () { + return
    Hello
    } export default MyComponent diff --git a/npm/react/package.json b/npm/react/package.json index a0f4d42f429f..bc72a7e8b8d0 100644 --- a/npm/react/package.json +++ b/npm/react/package.json @@ -17,25 +17,26 @@ }, "devDependencies": { "@cypress/mount-utils": "0.0.0-development", - "@types/semver": "7.5.0", - "@vitejs/plugin-react": "4.3.0", - "axios": "0.21.2", + "@types/semver": "7.5.8", + "@vitejs/plugin-react": "4.3.3", + "axios": "1.7.7", "cypress": "0.0.0-development", - "prop-types": "15.7.2", - "react": "17.0.2", - "react-dom": "17.0.2", - "react-router": "6.10.0", - "react-router-dom": "6.10.0", + "prop-types": "15.8.1", + "react": "18.3.1", + "react-dom": "18.3.1", + "react-router": "6.28.0", + "react-router-dom": "6.28.0", "semver": "^7.5.3", "typescript": "~5.4.5", - "vite": "5.2.11", + "vite": "5.4.10", "vite-plugin-require-transform": "1.0.12" }, "peerDependencies": { - "@types/react": "^16.9.16 || ^17.0.0", + "@types/react": "^18", + "@types/react-dom": "^18", "cypress": "*", - "react": "^=16.x || ^=17.x", - "react-dom": "^=16.x || ^=17.x" + "react": "^18", + "react-dom": "^18" }, "files": [ "dist" @@ -90,9 +91,6 @@ "nx": { "targets": { "build": { - "dependsOn": [ - "!@cypress/react18:build" - ], "outputs": [ "{workspaceRoot}/cli/react", "{projectRoot}/dist" diff --git a/npm/react/src/mount.ts b/npm/react/src/mount.ts index d4cb0fa21c93..f1904fac7663 100644 --- a/npm/react/src/mount.ts +++ b/npm/react/src/mount.ts @@ -1,23 +1,23 @@ -import { getContainerEl } from '@cypress/mount-utils' import React from 'react' -import ReactDOM from 'react-dom' -import major from 'semver/functions/major' +import ReactDOM from 'react-dom/client' +import { getContainerEl } from '@cypress/mount-utils' import { makeMountFn, makeUnmountFn, -} from './createMount' +} from './index' import type { MountOptions, InternalMountOptions, -} from './types' + UnmountArgs, +} from './index' -let lastReactDom: typeof ReactDOM +let root: ReactDOM.Root | null const cleanup = () => { - if (lastReactDom) { - const root = getContainerEl() + if (root) { + root.unmount() - lastReactDom.unmountComponentAtNode(root) + root = null return true } @@ -27,10 +27,10 @@ const cleanup = () => { /** * Mounts a React component into the DOM. - * @param jsx {React.ReactNode} The React component to mount. - * @param options {MountOptions} [options={}] options to pass to the mount function. - * @param rerenderKey {string} [rerenderKey] A key to use to force a rerender. - * @see {@link https://on.cypress.io/mounting-react} for more details. + * @param {import('react').JSX.Element} jsx The React component to mount. + * @param {MountOptions} options Options to pass to the mount function. + * @param {string} rerenderKey A key to use to force a rerender. + * * @example * import { mount } from '@cypress/react' * import { Stepper } from './Stepper' @@ -40,24 +40,24 @@ const cleanup = () => { * cy.get('[data-cy=increment]').click() * cy.get('[data-cy=counter]').should('have.text', '1') * } + * + * @see {@link https://on.cypress.io/mounting-react} for more details. + * + * @returns {Cypress.Chainable} The mounted component. */ export function mount (jsx: React.ReactNode, options: MountOptions = {}, rerenderKey?: string) { - if (major(React.version) === 18) { - const message = '[cypress/react]: You are using `cypress/react`, which is designed for React <= 17. Consider changing to `cypress/react18`, which is designed for React 18.' - - console.error(message) - Cypress.log({ name: 'warning', message }) - } - // Remove last mounted component if cy.mount is called more than once in a test + // React by default removes the last component when calling render, but we should remove the root + // to wipe away any state cleanup() - const internalOptions: InternalMountOptions = { reactDom: ReactDOM, - render: (reactComponent: ReturnType, el: HTMLElement, reactDomToUse: typeof ReactDOM) => { - lastReactDom = (reactDomToUse || ReactDOM) + render: (reactComponent: ReturnType, el: HTMLElement) => { + if (!root) { + root = ReactDOM.createRoot(el) + } - return lastReactDom.render(reactComponent, el) + return root.render(reactComponent) }, unmount: internalUnmount, cleanup, @@ -66,20 +66,14 @@ export function mount (jsx: React.ReactNode, options: MountOptions = {}, rerende return makeMountFn('mount', jsx, { ReactDom: ReactDOM, ...options }, rerenderKey, internalOptions) } -/** - * Unmounts the component from the DOM. - * @internal - * @param options - Options for unmounting. - */ function internalUnmount (options = { log: true }) { return makeUnmountFn(options) } - /** * Removed as of Cypress 11.0.0. * @see https://on.cypress.io/migration-11-0-0-component-testing-updates */ -export function unmount (options = { log: true }) { +export function unmount (options: UnmountArgs = { log: true }) { // @ts-expect-error - undocumented API Cypress.utils.throwErrByPath('mount.unmount') } diff --git a/npm/react/src/types.ts b/npm/react/src/types.ts index b13bbcb1246f..e9da14f24548 100644 --- a/npm/react/src/types.ts +++ b/npm/react/src/types.ts @@ -8,7 +8,7 @@ export interface UnmountArgs { export type MountOptions = Partial export interface MountReactComponentOptions { - ReactDom: typeof import('react-dom') + ReactDom: typeof import('react-dom/client') /** * Log the mounting command into Cypress Command Log, * true by default. @@ -22,11 +22,11 @@ export interface MountReactComponentOptions { } export interface InternalMountOptions { - reactDom: typeof import('react-dom') + reactDom: typeof import('react-dom/client') render: ( reactComponent: ReturnType, el: HTMLElement, - reactDomToUse: typeof import('react-dom') + reactDomToUse: typeof import('react-dom/client') ) => void unmount: (options: UnmountArgs) => void cleanup: () => boolean diff --git a/npm/react18/.eslintignore b/npm/react18/.eslintignore deleted file mode 100644 index 79afe972da7d..000000000000 --- a/npm/react18/.eslintignore +++ /dev/null @@ -1,5 +0,0 @@ -**/dist -**/*.d.ts -**/package-lock.json -**/tsconfig.json -**/cypress/fixtures \ No newline at end of file diff --git a/npm/react18/.releaserc.js b/npm/react18/.releaserc.js deleted file mode 100644 index 17d3bb871472..000000000000 --- a/npm/react18/.releaserc.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - ...require('../../.releaserc'), -} diff --git a/npm/react18/CHANGELOG.md b/npm/react18/CHANGELOG.md deleted file mode 100644 index 8afdf6422cc5..000000000000 --- a/npm/react18/CHANGELOG.md +++ /dev/null @@ -1,47 +0,0 @@ -# [@cypress/react18-v2.0.1](https://github.com/cypress-io/cypress/compare/@cypress/react18-v2.0.0...@cypress/react18-v2.0.1) (2024-06-07) - - -### Bug Fixes - -* update cypress to Typescript 5 ([#29568](https://github.com/cypress-io/cypress/issues/29568)) ([f3b6766](https://github.com/cypress-io/cypress/commit/f3b67666a5db0438594339c379cf27e1fd1e4abc)) - -# [@cypress/react18-v2.0.0](https://github.com/cypress-io/cypress/compare/@cypress/react18-v1.1.1...@cypress/react18-v2.0.0) (2022-11-07) - - -### Bug Fixes - -* 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)) - - -### BREAKING CHANGES - -* remove last mounted component upon subsequent mount calls of mount - -# [@cypress/react18-v1.1.1](https://github.com/cypress-io/cypress/compare/@cypress/react18-v1.1.0...@cypress/react18-v1.1.1) (2022-10-13) - - -### Bug Fixes - -* cypress/react18 rerender ([#23360](https://github.com/cypress-io/cypress/issues/23360)) ([8b8f20e](https://github.com/cypress-io/cypress/commit/8b8f20eec77d4c0a704aee7f7077dc92dbafb93f)) - -# [@cypress/react18-v1.1.0](https://github.com/cypress-io/cypress/compare/@cypress/react18-v1.0.1...@cypress/react18-v1.1.0) (2022-08-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/react18-v1.0.1](https://github.com/cypress-io/cypress/compare/@cypress/react18-v1.0.0...@cypress/react18-v1.0.1) (2022-08-15) - - -### Bug Fixes - -* **react18:** unmount component with react18 API ([#23204](https://github.com/cypress-io/cypress/issues/23204)) ([eab950b](https://github.com/cypress-io/cypress/commit/eab950bec013f9caf5836e3fa58670fde25e2684)) - -# @cypress/react18-v1.0.0 (2022-08-11) - - -### Features - -* React 18 support ([#22876](https://github.com/cypress-io/cypress/issues/22876)) ([f0d3a48](https://github.com/cypress-io/cypress/commit/f0d3a4867907bf6e60468510daa883ccc8dcfb63)) diff --git a/npm/react18/README.md b/npm/react18/README.md deleted file mode 100644 index 4f85d8081af8..000000000000 --- a/npm/react18/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# @cypress/react18 - -Mount React 18 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 [React Component Testing Docs](https://docs.cypress.io/guides/component-testing/react/overview) for mounting React components. Installing and importing `mount` from `@cypress/react18` should only be done for advanced use-cases. - -## [Changelog](./CHANGELOG.md) diff --git a/npm/react18/package.json b/npm/react18/package.json deleted file mode 100644 index 5104e75eb943..000000000000 --- a/npm/react18/package.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "name": "@cypress/react18", - "version": "0.0.0-development", - "description": "Test React components using Cypress", - "main": "dist/cypress-react.cjs.js", - "scripts": { - "build": "rimraf dist && rollup -c rollup.config.mjs", - "postbuild": "node ../../scripts/sync-exported-npm-with-cli.js", - "check-ts": "tsc --noEmit", - "lint": "eslint --ext .js,.jsx,.ts,.tsx,.json, .", - "watch": "yarn build --watch --watch.exclude ./dist/**/*" - }, - "devDependencies": { - "@cypress/mount-utils": "0.0.0-development", - "@cypress/react": "0.0.0-development", - "@rollup/plugin-commonjs": "^17.1.0", - "@rollup/plugin-node-resolve": "^11.1.1", - "@types/react": "17.0.83", - "@types/react-dom": "17.0.25", - "cypress": "0.0.0-development", - "react": "^17.0.2", - "react-dom": "^17.0.2", - "rollup": "3.7.3", - "rollup-plugin-typescript2": "^0.29.0", - "typescript": "~5.4.5" - }, - "peerDependencies": { - "@types/react": "^18", - "@types/react-dom": "^18", - "cypress": "*", - "react": "^18", - "react-dom": "^18" - }, - "files": [ - "dist" - ], - "types": "dist/index.d.ts", - "license": "MIT", - "repository": { - "type": "git", - "url": "https://github.com/cypress-io/cypress.git" - }, - "homepage": "https://github.com/cypress-io/cypress/blob/develop/npm/react18/#readme", - "bugs": "https://github.com/cypress-io/cypress/issues/new?assignees=&labels=npm%3A%20%40cypress%2Freact18&template=1-bug-report.md&title=", - "keywords": [ - "react", - "cypress", - "cypress-io", - "test", - "testing" - ], - "module": "dist/cypress-react.esm-bundler.js", - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - }, - "publishConfig": { - "access": "public" - }, - "nx": { - "targets": { - "build": { - "outputs": [ - "{workspaceRoot}/cli/react18", - "{projectRoot}/dist" - ] - } - } - } -} diff --git a/npm/react18/rollup.config.mjs b/npm/react18/rollup.config.mjs deleted file mode 100644 index db047e2bbd48..000000000000 --- a/npm/react18/rollup.config.mjs +++ /dev/null @@ -1,3 +0,0 @@ -import rollupConfig from '@cypress/react/rollup.config.mjs' - -export default rollupConfig diff --git a/npm/react18/src/index.ts b/npm/react18/src/index.ts deleted file mode 100644 index 9ab7390dfc87..000000000000 --- a/npm/react18/src/index.ts +++ /dev/null @@ -1,92 +0,0 @@ -import React from 'react' -import ReactDOM from 'react-dom/client' -import { getContainerEl } from '@cypress/mount-utils' -import { - makeMountFn, - makeUnmountFn, -} from '@cypress/react' -import type { - MountOptions, - MountReturn, - InternalMountOptions, - UnmountArgs, -} from '@cypress/react' - -let root: ReactDOM.Root | null - -const cleanup = () => { - if (root) { - root.unmount() - - root = null - - return true - } - - return false -} - -/** - * Mounts a React component into the DOM. - * @param {import('react').JSX.Element} jsx The React component to mount. - * @param {MountOptions} options Options to pass to the mount function. - * @param {string} rerenderKey A key to use to force a rerender. - * - * @example - * import { mount } from '@cypress/react' - * import { Stepper } from './Stepper' - * - * it('mounts', () => { - * mount() - * cy.get('[data-cy=increment]').click() - * cy.get('[data-cy=counter]').should('have.text', '1') - * } - * - * @see {@link https://on.cypress.io/mounting-react} for more details. - * - * @returns {Cypress.Chainable} The mounted component. - */ -export function mount (jsx: React.ReactNode, options: MountOptions = {}, rerenderKey?: string) { - // Remove last mounted component if cy.mount is called more than once in a test - // React by default removes the last component when calling render, but we should remove the root - // to wipe away any state - cleanup() - const internalOptions: InternalMountOptions = { - // @ts-expect-error - reactDom: ReactDOM, - render: (reactComponent: ReturnType, el: HTMLElement) => { - if (!root) { - root = ReactDOM.createRoot(el) - } - - return root.render(reactComponent) - }, - unmount: internalUnmount, - cleanup, - } - - // @ts-expect-error - return makeMountFn('mount', jsx, { ReactDom: ReactDOM, ...options }, rerenderKey, internalOptions) -} - -function internalUnmount (options = { log: true }) { - return makeUnmountFn(options) -} -/** - * Removed as of Cypress 11.0.0. - * @see https://on.cypress.io/migration-11-0-0-component-testing-updates - */ -export function unmount (options: UnmountArgs = { log: true }) { - // @ts-expect-error - undocumented API - Cypress.utils.throwErrByPath('mount.unmount') -} - -// Re-export this to help with migrating away from `unmount` -export { - getContainerEl, -} - -export type { - MountOptions, - MountReturn, -} diff --git a/npm/react18/tsconfig.json b/npm/react18/tsconfig.json deleted file mode 100644 index 8e6ae3e4c8a9..000000000000 --- a/npm/react18/tsconfig.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "compilerOptions": { - "target": "es5", - "module": "esnext", - "moduleResolution": "node", - "lib": [ - "es2015", - "dom" - ], - "rootDir": "src", - "outDir": "dist", - "declaration": true, - "strict": true, - "types": [ - "cypress" - ], - "allowSyntheticDefaultImports": true, - "esModuleInterop": true, - "resolveJsonModule": false - }, - "include": ["src/**/*.ts"] -} diff --git a/npm/vite-dev-server/cypress/e2e/vite-dev-server.cy.ts b/npm/vite-dev-server/cypress/e2e/vite-dev-server.cy.ts index 7c4959580c45..fb11182beacc 100644 --- a/npm/vite-dev-server/cypress/e2e/vite-dev-server.cy.ts +++ b/npm/vite-dev-server/cypress/e2e/vite-dev-server.cy.ts @@ -19,7 +19,7 @@ describe('Config options', () => { await ctx.actions.file.writeFileInProject( 'src/App.cy.jsx', ` import React from 'react' - import { mount } from 'cypress/react18' + import { mount } from 'cypress/react' export const App = () => { return ( diff --git a/npm/vite-plugin-cypress-esm/README.md b/npm/vite-plugin-cypress-esm/README.md index 97cb3aed2d5a..422b211f1b1b 100644 --- a/npm/vite-plugin-cypress-esm/README.md +++ b/npm/vite-plugin-cypress-esm/README.md @@ -10,8 +10,8 @@ Run Cypress with `DEBUG=cypress:vite-plugin-cypress-esm`. You will get logs in t ## Compatibility | @cypress/vite-plugin-cypress-esm | cypress | -| ------------------------ | ------- | -| >= v1 | >= v12 | +| -------------------------------- | ------- | +| >= v1 | >= v12 | ## Usage @@ -80,6 +80,14 @@ CypressEsm({ }) ``` +If using the `@cypress/react` test harness, you may need to ignore the `react-dom/client` module by configuring as such: + +```ts +CypressEsm({ + ignoreImportList: ['**/react-dom/client'] +}) +``` + ## Known Issues ### Import Syntax diff --git a/npm/vite-plugin-cypress-esm/cypress.config.ts b/npm/vite-plugin-cypress-esm/cypress.config.ts index 3ea2aa0a48f5..88778d7d2290 100644 --- a/npm/vite-plugin-cypress-esm/cypress.config.ts +++ b/npm/vite-plugin-cypress-esm/cypress.config.ts @@ -13,12 +13,11 @@ export default defineConfig({ viteConfig: () => { return { plugins: [ - react({ - jsxRuntime: 'classic', - }), + react(), CypressEsm({ ignoreModuleList: ['**/ignoreModuleList.cy.ts', '*MyAsync*'], - ignoreImportList: ['**/ImmutableModuleB*'], + // For `cypress/react` on react 18+, we need to ignore transforming the react-dom/client library + ignoreImportList: ['**/ImmutableModuleB*', '**/react-dom/client'], }), ], } diff --git a/npm/vite-plugin-cypress-esm/package.json b/npm/vite-plugin-cypress-esm/package.json index d7b5f214f551..f111d493a2b7 100644 --- a/npm/vite-plugin-cypress-esm/package.json +++ b/npm/vite-plugin-cypress-esm/package.json @@ -19,11 +19,11 @@ "devDependencies": { "@tanstack/react-query": "4.36.1", "@types/picomatch": "2.3.0", - "@vitejs/plugin-react": "4.3.0", - "react": "16.8.6", - "react-dom": "16.8.6", - "react-router": "6.10.0", - "react-router-dom": "6.10.0", + "@vitejs/plugin-react": "4.3.3", + "react": "18.3.1", + "react-dom": "18.3.1", + "react-router": "6.28.0", + "react-router-dom": "6.28.0", "vite": "5.2.11" }, "files": [ diff --git a/npm/vue/package.json b/npm/vue/package.json index 147a496893c1..b0544dde24d1 100644 --- a/npm/vue/package.json +++ b/npm/vue/package.json @@ -82,9 +82,6 @@ "nx": { "targets": { "build": { - "dependsOn": [ - "!@cypress/react18:build" - ], "outputs": [ "{workspaceRoot}/cli/vue", "{projectRoot}/dist" diff --git a/npm/webpack-preprocessor/package.json b/npm/webpack-preprocessor/package.json index 61b8978b67b9..0a614f0051c1 100644 --- a/npm/webpack-preprocessor/package.json +++ b/npm/webpack-preprocessor/package.json @@ -70,9 +70,6 @@ "nx": { "targets": { "build": { - "dependsOn": [ - "!@cypress/react18:build" - ], "outputs": [ "{projectRoot}/dist" ] diff --git a/packages/launchpad/cypress/e2e/config-warning.cy.ts b/packages/launchpad/cypress/e2e/config-warning.cy.ts index 6ae9a48de1e9..a006556dc3a6 100644 --- a/packages/launchpad/cypress/e2e/config-warning.cy.ts +++ b/packages/launchpad/cypress/e2e/config-warning.cy.ts @@ -203,8 +203,8 @@ describe('component testing dependency warnings', () => { cy.get('[data-cy="warning-alert"]', { timeout: 12000 }).should('exist') .should('contain.text', 'Warning: Component Testing Mismatched Dependencies') .should('contain.text', 'vite. Expected ^4.0.0 || ^5.0.0, found 3.2.11') - .should('contain.text', 'react. Expected ^16.0.0 || ^17.0.0 || ^18.0.0, found 15.6.2.') - .should('contain.text', 'react-dom. Expected ^16.0.0 || ^17.0.0 || ^18.0.0 but dependency was not found.') + .should('contain.text', 'react. Expected ^18.0.0, found 15.6.2.') + .should('contain.text', 'react-dom. Expected ^18.0.0 but dependency was not found.') cy.get('.warning-markdown').find('li').should('have.length', 3) }) diff --git a/packages/reporter/cypress/support/component.ts b/packages/reporter/cypress/support/component.ts index 7ffa238e8510..4fe6c1860b90 100644 --- a/packages/reporter/cypress/support/component.ts +++ b/packages/reporter/cypress/support/component.ts @@ -1,4 +1,4 @@ -import { mount } from 'cypress/react18' +import { mount } from 'cypress/react' import 'cypress-real-events/support' import { installCustomPercyCommand } from '@packages/frontend-shared/cypress/support/customPercyCommand' diff --git a/packages/scaffold-config/src/dependencies.ts b/packages/scaffold-config/src/dependencies.ts index eeaa1e96da7d..61f92f7835a0 100644 --- a/packages/scaffold-config/src/dependencies.ts +++ b/packages/scaffold-config/src/dependencies.ts @@ -22,7 +22,7 @@ export const WIZARD_DEPENDENCY_REACT = { package: 'react', installer: 'react', description: 'A JavaScript library for building user interfaces', - minVersion: '^16.0.0 || ^17.0.0 || ^18.0.0', + minVersion: '^18.0.0', } as const export const WIZARD_DEPENDENCY_REACT_DOM = { @@ -31,7 +31,7 @@ export const WIZARD_DEPENDENCY_REACT_DOM = { package: 'react-dom', installer: 'react-dom', description: 'This package serves as the entry point to the DOM and server renderers for React', - minVersion: '^16.0.0 || ^17.0.0 || ^18.0.0', + minVersion: '^18.0.0', } as const export const WIZARD_DEPENDENCY_TYPESCRIPT = { diff --git a/packages/scaffold-config/src/frameworks.ts b/packages/scaffold-config/src/frameworks.ts index 9c909d4ace9b..cf914d1c6903 100644 --- a/packages/scaffold-config/src/frameworks.ts +++ b/packages/scaffold-config/src/frameworks.ts @@ -101,16 +101,6 @@ export function getBundler (bundler: WizardBundler['type']): WizardBundler { const mountModule = (mountModule: T) => (projectPath: string) => Promise.resolve(mountModule) -const reactMountModule = async (projectPath: string) => { - const reactPkg = await isDependencyInstalled(dependencies.WIZARD_DEPENDENCY_REACT, projectPath) - - if (!reactPkg.detectedVersion || !semver.valid(reactPkg.detectedVersion)) { - return 'cypress/react' - } - - return semver.major(reactPkg.detectedVersion) === 18 ? 'cypress/react18' : 'cypress/react' -} - export const SUPPORT_STATUSES: Readonly = ['alpha', 'beta', 'full', 'community'] as const export const CT_FRAMEWORKS: Cypress.ComponentFrameworkDefinition[] = [ @@ -130,7 +120,7 @@ export const CT_FRAMEWORKS: Cypress.ComponentFrameworkDefinition[] = [ }, codeGenFramework: 'react', glob: '*.{js,jsx,tsx}', - mountModule: reactMountModule, + mountModule: mountModule('cypress/react'), supportStatus: 'full', /** * Next.js uses style-loader to inject CSS and requires this element to exist in the HTML. @@ -176,7 +166,7 @@ export const CT_FRAMEWORKS: Cypress.ComponentFrameworkDefinition[] = [ }, codeGenFramework: 'react', glob: '*.{js,jsx,tsx}', - mountModule: reactMountModule, + mountModule: mountModule('cypress/react'), supportStatus: 'full', componentIndexHtml: componentIndexHtmlGenerator(), }, diff --git a/packages/scaffold-config/test/unit/supportFile.spec.ts b/packages/scaffold-config/test/unit/supportFile.spec.ts index 745d76791a3c..ac0e12d6bec1 100644 --- a/packages/scaffold-config/test/unit/supportFile.spec.ts +++ b/packages/scaffold-config/test/unit/supportFile.spec.ts @@ -4,11 +4,12 @@ import { expect } from 'chai' describe('supportFileComponent', () => { context('react', () => { - for (const mountModule of ['cypress/react', 'cypress/react18'] as const) { - it(`handles ${mountModule} and JS`, () => { - const actual = supportFileComponent('js', mountModule) + const mountModule = 'cypress/react' - expect(actual).to.eq(dedent` + it(`handles ${mountModule} and JS`, () => { + const actual = supportFileComponent('js', mountModule) + + expect(actual).to.eq(dedent` // *********************************************************** // This example support/component.js is processed and // loaded automatically before your test files. @@ -37,12 +38,12 @@ describe('supportFileComponent', () => { // Example use: // cy.mount() `) - }) + }) - it(`handles ${mountModule} and TS`, () => { - const actual = supportFileComponent('ts', mountModule) + it(`handles ${mountModule} and TS`, () => { + const actual = supportFileComponent('ts', mountModule) - expect(actual).to.eq(dedent` + expect(actual).to.eq(dedent` // *********************************************************** // This example support/component.ts is processed and // loaded automatically before your test files. @@ -83,8 +84,7 @@ describe('supportFileComponent', () => { // Example use: // cy.mount() `) - }) - } + }) }) context('vue', () => { diff --git a/system-tests/__snapshots__/component_testing_spec.ts.js b/system-tests/__snapshots__/component_testing_spec.ts.js index 6172ed3738f4..b0f037b039b8 100644 --- a/system-tests/__snapshots__/component_testing_spec.ts.js +++ b/system-tests/__snapshots__/component_testing_spec.ts.js @@ -7,16 +7,14 @@ exports['React major versions with Webpack executes all of the tests for React v ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Cypress: 1.2.3 │ │ Browser: FooBrowser 88 │ - │ Specs: 5 found (App.cy.jsx, Unmount.cy.jsx, UsingLegacyMount.cy.jsx, Rerendering.cy.jsx, │ - │ mount.cy.jsx) │ - │ Searched: src/App.cy.jsx, src/Unmount.cy.jsx, src/UsingLegacyMount.cy.jsx, src/Rerendering.c │ - │ y.jsx, src/mount.cy.jsx │ + │ Specs: 4 found (App.cy.jsx, Unmount.cy.jsx, Rerendering.cy.jsx, mount.cy.jsx) │ + │ Searched: src/App.cy.jsx, src/Unmount.cy.jsx, src/Rerendering.cy.jsx, src/mount.cy.jsx │ └────────────────────────────────────────────────────────────────────────────────────────────────┘ ──────────────────────────────────────────────────────────────────────────────────────────────────── - Running: App.cy.jsx (1 of 5) + Running: App.cy.jsx (1 of 4) ✓ renders hello world @@ -42,7 +40,7 @@ exports['React major versions with Webpack executes all of the tests for React v ──────────────────────────────────────────────────────────────────────────────────────────────────── - Running: Unmount.cy.jsx (2 of 5) + Running: Unmount.cy.jsx (2 of 4) Comp with componentWillUnmount @@ -73,393 +71,7 @@ exports['React major versions with Webpack executes all of the tests for React v ──────────────────────────────────────────────────────────────────────────────────────────────────── - Running: UsingLegacyMount.cy.jsx (3 of 5) - - - using legacy mount - ✓ issues a warning encouraging user to update - - - 1 passing - - - (Results) - - ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ - │ Tests: 1 │ - │ Passing: 1 │ - │ Failing: 0 │ - │ Pending: 0 │ - │ Skipped: 0 │ - │ Screenshots: 0 │ - │ Video: false │ - │ Duration: X seconds │ - │ Spec Ran: UsingLegacyMount.cy.jsx │ - └────────────────────────────────────────────────────────────────────────────────────────────────┘ - - -──────────────────────────────────────────────────────────────────────────────────────────────────── - - Running: Rerendering.cy.jsx (4 of 5) - - - re-render - ✓ maintains component state across re-renders - - - 1 passing - - - (Results) - - ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ - │ Tests: 1 │ - │ Passing: 1 │ - │ Failing: 0 │ - │ Pending: 0 │ - │ Skipped: 0 │ - │ Screenshots: 0 │ - │ Video: false │ - │ Duration: X seconds │ - │ Spec Ran: Rerendering.cy.jsx │ - └────────────────────────────────────────────────────────────────────────────────────────────────┘ - - -──────────────────────────────────────────────────────────────────────────────────────────────────── - - Running: mount.cy.jsx (5 of 5) - - - mount - ✓ does not error when rendering primitives - teardown - ✓ should mount - ✓ should remove previous mounted component - - - 3 passing - - - (Results) - - ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ - │ Tests: 3 │ - │ Passing: 3 │ - │ Failing: 0 │ - │ Pending: 0 │ - │ Skipped: 0 │ - │ Screenshots: 0 │ - │ Video: false │ - │ Duration: X seconds │ - │ Spec Ran: mount.cy.jsx │ - └────────────────────────────────────────────────────────────────────────────────────────────────┘ - - -==================================================================================================== - - (Run Finished) - - - Spec Tests Passing Failing Pending Skipped - ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ - │ ✔ App.cy.jsx XX:XX 2 2 - - - │ - ├────────────────────────────────────────────────────────────────────────────────────────────────┤ - │ ✔ Unmount.cy.jsx XX:XX 3 3 - - - │ - ├────────────────────────────────────────────────────────────────────────────────────────────────┤ - │ ✔ UsingLegacyMount.cy.jsx XX:XX 1 1 - - - │ - ├────────────────────────────────────────────────────────────────────────────────────────────────┤ - │ ✔ Rerendering.cy.jsx XX:XX 1 1 - - - │ - ├────────────────────────────────────────────────────────────────────────────────────────────────┤ - │ ✔ mount.cy.jsx XX:XX 3 3 - - - │ - └────────────────────────────────────────────────────────────────────────────────────────────────┘ - ✔ All specs passed! XX:XX 10 10 - - - - - -` - -exports['React major versions with Webpack executes all of the tests for React v17 with Webpack 1'] = ` - -==================================================================================================== - - (Run Starting) - - ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ - │ Cypress: 1.2.3 │ - │ Browser: FooBrowser 88 │ - │ Specs: 5 found (App.cy.jsx, Unmount.cy.jsx, UsingLegacyMount.cy.jsx, Rerendering.cy.jsx, │ - │ mount.cy.jsx) │ - │ Searched: src/App.cy.jsx, src/Unmount.cy.jsx, src/UsingLegacyMount.cy.jsx, src/Rerendering.c │ - │ y.jsx, src/mount.cy.jsx │ - └────────────────────────────────────────────────────────────────────────────────────────────────┘ - - -──────────────────────────────────────────────────────────────────────────────────────────────────── - - Running: App.cy.jsx (1 of 5) - 50 modules - - - ✓ renders hello world - ✓ renders background - - 2 passing - - - (Results) - - ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ - │ Tests: 2 │ - │ Passing: 2 │ - │ Failing: 0 │ - │ Pending: 0 │ - │ Skipped: 0 │ - │ Screenshots: 0 │ - │ Video: false │ - │ Duration: X seconds │ - │ Spec Ran: App.cy.jsx │ - └────────────────────────────────────────────────────────────────────────────────────────────────┘ - - -──────────────────────────────────────────────────────────────────────────────────────────────────── - - Running: Unmount.cy.jsx (2 of 5) - - - Comp with componentWillUnmount - ✓ calls the prop - - mount cleanup - ✓ mount 1 - ✓ mount 2 - - - 3 passing - - - (Results) - - ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ - │ Tests: 3 │ - │ Passing: 3 │ - │ Failing: 0 │ - │ Pending: 0 │ - │ Skipped: 0 │ - │ Screenshots: 0 │ - │ Video: false │ - │ Duration: X seconds │ - │ Spec Ran: Unmount.cy.jsx │ - └────────────────────────────────────────────────────────────────────────────────────────────────┘ - - -──────────────────────────────────────────────────────────────────────────────────────────────────── - - Running: UsingLegacyMount.cy.jsx (3 of 5) - - - using legacy mount - ✓ does not warning or log - - - 1 passing - - - (Results) - - ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ - │ Tests: 1 │ - │ Passing: 1 │ - │ Failing: 0 │ - │ Pending: 0 │ - │ Skipped: 0 │ - │ Screenshots: 0 │ - │ Video: false │ - │ Duration: X seconds │ - │ Spec Ran: UsingLegacyMount.cy.jsx │ - └────────────────────────────────────────────────────────────────────────────────────────────────┘ - - -──────────────────────────────────────────────────────────────────────────────────────────────────── - - Running: Rerendering.cy.jsx (4 of 5) - - - re-render - ✓ maintains component state across re-renders - - - 1 passing - - - (Results) - - ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ - │ Tests: 1 │ - │ Passing: 1 │ - │ Failing: 0 │ - │ Pending: 0 │ - │ Skipped: 0 │ - │ Screenshots: 0 │ - │ Video: false │ - │ Duration: X seconds │ - │ Spec Ran: Rerendering.cy.jsx │ - └────────────────────────────────────────────────────────────────────────────────────────────────┘ - - -──────────────────────────────────────────────────────────────────────────────────────────────────── - - Running: mount.cy.jsx (5 of 5) - - - mount - ✓ does not error when rendering primitives - teardown - ✓ should mount - ✓ should remove previous mounted component - - - 3 passing - - - (Results) - - ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ - │ Tests: 3 │ - │ Passing: 3 │ - │ Failing: 0 │ - │ Pending: 0 │ - │ Skipped: 0 │ - │ Screenshots: 0 │ - │ Video: false │ - │ Duration: X seconds │ - │ Spec Ran: mount.cy.jsx │ - └────────────────────────────────────────────────────────────────────────────────────────────────┘ - - -==================================================================================================== - - (Run Finished) - - - Spec Tests Passing Failing Pending Skipped - ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ - │ ✔ App.cy.jsx XX:XX 2 2 - - - │ - ├────────────────────────────────────────────────────────────────────────────────────────────────┤ - │ ✔ Unmount.cy.jsx XX:XX 3 3 - - - │ - ├────────────────────────────────────────────────────────────────────────────────────────────────┤ - │ ✔ UsingLegacyMount.cy.jsx XX:XX 1 1 - - - │ - ├────────────────────────────────────────────────────────────────────────────────────────────────┤ - │ ✔ Rerendering.cy.jsx XX:XX 1 1 - - - │ - ├────────────────────────────────────────────────────────────────────────────────────────────────┤ - │ ✔ mount.cy.jsx XX:XX 3 3 - - - │ - └────────────────────────────────────────────────────────────────────────────────────────────────┘ - ✔ All specs passed! XX:XX 10 10 - - - - - -` - -exports['React major versions with Vite executes all of the tests for React v17 with Vite 1'] = ` - -==================================================================================================== - - (Run Starting) - - ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ - │ Cypress: 1.2.3 │ - │ Browser: FooBrowser 88 │ - │ Specs: 5 found (App.cy.jsx, Unmount.cy.jsx, UsingLegacyMount.cy.jsx, Rerendering.cy.jsx, │ - │ mount.cy.jsx) │ - │ Searched: src/App.cy.jsx, src/Unmount.cy.jsx, src/UsingLegacyMount.cy.jsx, src/Rerendering.c │ - │ y.jsx, src/mount.cy.jsx │ - └────────────────────────────────────────────────────────────────────────────────────────────────┘ - - -──────────────────────────────────────────────────────────────────────────────────────────────────── - - Running: App.cy.jsx (1 of 5) - - - ✓ renders hello world - ✓ renders background - - 2 passing - - - (Results) - - ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ - │ Tests: 2 │ - │ Passing: 2 │ - │ Failing: 0 │ - │ Pending: 0 │ - │ Skipped: 0 │ - │ Screenshots: 0 │ - │ Video: false │ - │ Duration: X seconds │ - │ Spec Ran: App.cy.jsx │ - └────────────────────────────────────────────────────────────────────────────────────────────────┘ - - -──────────────────────────────────────────────────────────────────────────────────────────────────── - - Running: Unmount.cy.jsx (2 of 5) - - - Comp with componentWillUnmount - ✓ calls the prop - - mount cleanup - ✓ mount 1 - ✓ mount 2 - - - 3 passing - - - (Results) - - ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ - │ Tests: 3 │ - │ Passing: 3 │ - │ Failing: 0 │ - │ Pending: 0 │ - │ Skipped: 0 │ - │ Screenshots: 0 │ - │ Video: false │ - │ Duration: X seconds │ - │ Spec Ran: Unmount.cy.jsx │ - └────────────────────────────────────────────────────────────────────────────────────────────────┘ - - -──────────────────────────────────────────────────────────────────────────────────────────────────── - - Running: UsingLegacyMount.cy.jsx (3 of 5) - - - using legacy mount - ✓ does not warning or log - - - 1 passing - - - (Results) - - ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ - │ Tests: 1 │ - │ Passing: 1 │ - │ Failing: 0 │ - │ Pending: 0 │ - │ Skipped: 0 │ - │ Screenshots: 0 │ - │ Video: false │ - │ Duration: X seconds │ - │ Spec Ran: UsingLegacyMount.cy.jsx │ - └────────────────────────────────────────────────────────────────────────────────────────────────┘ - - -──────────────────────────────────────────────────────────────────────────────────────────────────── - - Running: Rerendering.cy.jsx (4 of 5) + Running: Rerendering.cy.jsx (3 of 4) re-render @@ -486,7 +98,7 @@ exports['React major versions with Vite executes all of the tests for React v17 ──────────────────────────────────────────────────────────────────────────────────────────────────── - Running: mount.cy.jsx (5 of 5) + Running: mount.cy.jsx (4 of 4) mount @@ -525,13 +137,11 @@ exports['React major versions with Vite executes all of the tests for React v17 ├────────────────────────────────────────────────────────────────────────────────────────────────┤ │ ✔ Unmount.cy.jsx XX:XX 3 3 - - - │ ├────────────────────────────────────────────────────────────────────────────────────────────────┤ - │ ✔ UsingLegacyMount.cy.jsx XX:XX 1 1 - - - │ - ├────────────────────────────────────────────────────────────────────────────────────────────────┤ │ ✔ Rerendering.cy.jsx XX:XX 1 1 - - - │ ├────────────────────────────────────────────────────────────────────────────────────────────────┤ │ ✔ mount.cy.jsx XX:XX 3 3 - - - │ └────────────────────────────────────────────────────────────────────────────────────────────────┘ - ✔ All specs passed! XX:XX 10 10 - - - + ✔ All specs passed! XX:XX 9 9 - - - ` @@ -545,16 +155,14 @@ exports['React major versions with Vite executes all of the tests for React v18 ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Cypress: 1.2.3 │ │ Browser: FooBrowser 88 │ - │ Specs: 5 found (App.cy.jsx, Unmount.cy.jsx, UsingLegacyMount.cy.jsx, Rerendering.cy.jsx, │ - │ mount.cy.jsx) │ - │ Searched: src/App.cy.jsx, src/Unmount.cy.jsx, src/UsingLegacyMount.cy.jsx, src/Rerendering.c │ - │ y.jsx, src/mount.cy.jsx │ + │ Specs: 4 found (App.cy.jsx, Unmount.cy.jsx, Rerendering.cy.jsx, mount.cy.jsx) │ + │ Searched: src/App.cy.jsx, src/Unmount.cy.jsx, src/Rerendering.cy.jsx, src/mount.cy.jsx │ └────────────────────────────────────────────────────────────────────────────────────────────────┘ ──────────────────────────────────────────────────────────────────────────────────────────────────── - Running: App.cy.jsx (1 of 5) + Running: App.cy.jsx (1 of 4) ✓ renders hello world @@ -580,7 +188,7 @@ exports['React major versions with Vite executes all of the tests for React v18 ──────────────────────────────────────────────────────────────────────────────────────────────────── - Running: Unmount.cy.jsx (2 of 5) + Running: Unmount.cy.jsx (2 of 4) Comp with componentWillUnmount @@ -611,34 +219,7 @@ exports['React major versions with Vite executes all of the tests for React v18 ──────────────────────────────────────────────────────────────────────────────────────────────────── - Running: UsingLegacyMount.cy.jsx (3 of 5) - - - using legacy mount - ✓ issues a warning encouraging user to update - - - 1 passing - - - (Results) - - ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ - │ Tests: 1 │ - │ Passing: 1 │ - │ Failing: 0 │ - │ Pending: 0 │ - │ Skipped: 0 │ - │ Screenshots: 0 │ - │ Video: false │ - │ Duration: X seconds │ - │ Spec Ran: UsingLegacyMount.cy.jsx │ - └────────────────────────────────────────────────────────────────────────────────────────────────┘ - - -──────────────────────────────────────────────────────────────────────────────────────────────────── - - Running: Rerendering.cy.jsx (4 of 5) + Running: Rerendering.cy.jsx (3 of 4) re-render @@ -665,7 +246,7 @@ exports['React major versions with Vite executes all of the tests for React v18 ──────────────────────────────────────────────────────────────────────────────────────────────────── - Running: mount.cy.jsx (5 of 5) + Running: mount.cy.jsx (4 of 4) mount @@ -704,13 +285,11 @@ exports['React major versions with Vite executes all of the tests for React v18 ├────────────────────────────────────────────────────────────────────────────────────────────────┤ │ ✔ Unmount.cy.jsx XX:XX 3 3 - - - │ ├────────────────────────────────────────────────────────────────────────────────────────────────┤ - │ ✔ UsingLegacyMount.cy.jsx XX:XX 1 1 - - - │ - ├────────────────────────────────────────────────────────────────────────────────────────────────┤ │ ✔ Rerendering.cy.jsx XX:XX 1 1 - - - │ ├────────────────────────────────────────────────────────────────────────────────────────────────┤ │ ✔ mount.cy.jsx XX:XX 3 3 - - - │ └────────────────────────────────────────────────────────────────────────────────────────────────┘ - ✔ All specs passed! XX:XX 10 10 - - - + ✔ All specs passed! XX:XX 9 9 - - - ` diff --git a/system-tests/project-fixtures/react/cypress/support/component.js b/system-tests/project-fixtures/react/cypress/support/component.js index 96736d7047cb..fd025808277a 100644 --- a/system-tests/project-fixtures/react/cypress/support/component.js +++ b/system-tests/project-fixtures/react/cypress/support/component.js @@ -1,4 +1,4 @@ -import { mount } from 'cypress/react18' +import { mount } from 'cypress/react' import './backgroundColor.css' diff --git a/system-tests/project-fixtures/runner-specs/cypress/support/component.js b/system-tests/project-fixtures/runner-specs/cypress/support/component.js index 70284198ed61..86674a7a022b 100644 --- a/system-tests/project-fixtures/runner-specs/cypress/support/component.js +++ b/system-tests/project-fixtures/runner-specs/cypress/support/component.js @@ -1,3 +1,3 @@ -import { mount } from 'cypress/react18' +import { mount } from 'cypress/react' Cypress.Commands.add('mount', mount) diff --git a/system-tests/projects/cypress-in-cypress/src/NewComponent.spec.jsx b/system-tests/projects/cypress-in-cypress/src/NewComponent.spec.jsx index fe8ee97c541a..a202ae027161 100644 --- a/system-tests/projects/cypress-in-cypress/src/NewComponent.spec.jsx +++ b/system-tests/projects/cypress-in-cypress/src/NewComponent.spec.jsx @@ -1,5 +1,5 @@ import React from 'react' -import { mount } from 'cypress/react18' +import { mount } from 'cypress/react' describe('NewComponent', () => { it('renders the new component', () => { diff --git a/system-tests/projects/cypress-in-cypress/src/TestComponent.spec.jsx b/system-tests/projects/cypress-in-cypress/src/TestComponent.spec.jsx index 214c74d911cf..0324c25cf485 100644 --- a/system-tests/projects/cypress-in-cypress/src/TestComponent.spec.jsx +++ b/system-tests/projects/cypress-in-cypress/src/TestComponent.spec.jsx @@ -1,5 +1,5 @@ import React from 'react' -import { mount } from 'cypress/react18' +import { mount } from 'cypress/react' describe('TestComponent', () => { it('renders the test component', () => { diff --git a/system-tests/projects/experimental-JIT/vite/cypress/support/component.js b/system-tests/projects/experimental-JIT/vite/cypress/support/component.js index 70284198ed61..86674a7a022b 100644 --- a/system-tests/projects/experimental-JIT/vite/cypress/support/component.js +++ b/system-tests/projects/experimental-JIT/vite/cypress/support/component.js @@ -1,3 +1,3 @@ -import { mount } from 'cypress/react18' +import { mount } from 'cypress/react' Cypress.Commands.add('mount', mount) diff --git a/system-tests/projects/experimental-JIT/webpack/cypress/support/component.js b/system-tests/projects/experimental-JIT/webpack/cypress/support/component.js index 70284198ed61..86674a7a022b 100644 --- a/system-tests/projects/experimental-JIT/webpack/cypress/support/component.js +++ b/system-tests/projects/experimental-JIT/webpack/cypress/support/component.js @@ -1,3 +1,3 @@ -import { mount } from 'cypress/react18' +import { mount } from 'cypress/react' Cypress.Commands.add('mount', mount) diff --git a/system-tests/projects/next-14-tsconfig-tailwind/cypress/support/component.ts b/system-tests/projects/next-14-tsconfig-tailwind/cypress/support/component.ts index 44bd3a01d77e..81d0e5e698cb 100644 --- a/system-tests/projects/next-14-tsconfig-tailwind/cypress/support/component.ts +++ b/system-tests/projects/next-14-tsconfig-tailwind/cypress/support/component.ts @@ -1,6 +1,6 @@ import 'tailwindcss/tailwind.css' -import { mount } from 'cypress/react18' +import { mount } from 'cypress/react' declare global { namespace Cypress { diff --git a/system-tests/projects/nextjs-configured/components/button.cy.jsx b/system-tests/projects/nextjs-configured/components/button.cy.jsx index 02e1ca0a1a77..7078df6ba3b8 100644 --- a/system-tests/projects/nextjs-configured/components/button.cy.jsx +++ b/system-tests/projects/nextjs-configured/components/button.cy.jsx @@ -1,5 +1,5 @@ import React from 'react' -import { mount } from 'cypress/react18' +import { mount } from 'cypress/react' import { Button } from './button' it('works', () => { diff --git a/system-tests/projects/nextjs-unconfigured/components/button.cy.jsx b/system-tests/projects/nextjs-unconfigured/components/button.cy.jsx index 02e1ca0a1a77..7078df6ba3b8 100644 --- a/system-tests/projects/nextjs-unconfigured/components/button.cy.jsx +++ b/system-tests/projects/nextjs-unconfigured/components/button.cy.jsx @@ -1,5 +1,5 @@ import React from 'react' -import { mount } from 'cypress/react18' +import { mount } from 'cypress/react' import { Button } from './button' it('works', () => { diff --git a/system-tests/projects/no-specs/cypress/support/component.js b/system-tests/projects/no-specs/cypress/support/component.js index b70bd8c84f3a..be20eaa89ea2 100644 --- a/system-tests/projects/no-specs/cypress/support/component.js +++ b/system-tests/projects/no-specs/cypress/support/component.js @@ -19,7 +19,7 @@ import './commands' // Alternatively you can use CommonJS syntax: // require('./commands') -import { mount } from 'cypress/react18' +import { mount } from 'cypress/react' Cypress.Commands.add('mount', mount) diff --git a/system-tests/projects/protocol/cypress/support/component.ts b/system-tests/projects/protocol/cypress/support/component.ts index 52b74e5f5862..b3c30eabe612 100644 --- a/system-tests/projects/protocol/cypress/support/component.ts +++ b/system-tests/projects/protocol/cypress/support/component.ts @@ -1,4 +1,4 @@ -import { mount } from 'cypress/react18' +import { mount } from 'cypress/react' // Augment the Cypress namespace to include type definitions for // your custom command. diff --git a/system-tests/projects/react-vite-ts-configured/src/App.cy.tsx b/system-tests/projects/react-vite-ts-configured/src/App.cy.tsx index 08fe40cbe427..4b2373579092 100644 --- a/system-tests/projects/react-vite-ts-configured/src/App.cy.tsx +++ b/system-tests/projects/react-vite-ts-configured/src/App.cy.tsx @@ -1,5 +1,5 @@ import React from 'react' -import { mount } from 'cypress/react18' +import { mount } from 'cypress/react' import App from './App.tsx' it('works', () => { diff --git a/system-tests/projects/react18/cypress/support/component.js b/system-tests/projects/react18/cypress/support/component.js index 96736d7047cb..fd025808277a 100644 --- a/system-tests/projects/react18/cypress/support/component.js +++ b/system-tests/projects/react18/cypress/support/component.js @@ -1,4 +1,4 @@ -import { mount } from 'cypress/react18' +import { mount } from 'cypress/react' import './backgroundColor.css' diff --git a/system-tests/projects/react18/src/UsingLegacyMount.cy.jsx b/system-tests/projects/react18/src/UsingLegacyMount.cy.jsx deleted file mode 100644 index 3bb5e5147cbc..000000000000 --- a/system-tests/projects/react18/src/UsingLegacyMount.cy.jsx +++ /dev/null @@ -1,23 +0,0 @@ -import React from 'react' -import { mount } from 'cypress/react' - -function App () { - return

    Hello world

    -} - -describe('using legacy mount', () => { - it('issues a warning encouraging user to update', () => { - // dont log else we create an endless loop! - const log = cy.spy(Cypress, 'log').log(false) - const err = cy.spy(console, 'error') - - mount().get('h1').contains('Hello world') - .then(() => { - const msg = '[cypress/react]: You are using `cypress/react`, which is designed for React <= 17. Consider changing to `cypress/react18`, which is designed for React 18.' - const warning = log.getCalls().find((call) => call.args[0].name === 'warning') - - expect(warning.lastArg.message).to.eq(msg) - expect(err).to.have.been.calledWith(msg) - }) - }) -}) diff --git a/system-tests/projects/tailwind-vite/src/App.cy.jsx b/system-tests/projects/tailwind-vite/src/App.cy.jsx index 9bfbd96f48a5..c37ea8ba9b9f 100644 --- a/system-tests/projects/tailwind-vite/src/App.cy.jsx +++ b/system-tests/projects/tailwind-vite/src/App.cy.jsx @@ -1,5 +1,5 @@ import React from 'react' -import { mount } from 'cypress/react18' +import { mount } from 'cypress/react' export const App = () => { return ( diff --git a/system-tests/projects/vite-simple/cypress/support/component.js b/system-tests/projects/vite-simple/cypress/support/component.js index 70284198ed61..86674a7a022b 100644 --- a/system-tests/projects/vite-simple/cypress/support/component.js +++ b/system-tests/projects/vite-simple/cypress/support/component.js @@ -1,3 +1,3 @@ -import { mount } from 'cypress/react18' +import { mount } from 'cypress/react' Cypress.Commands.add('mount', mount) diff --git a/system-tests/projects/webpack-dev-server-relative/src/relative-url.cy.jsx b/system-tests/projects/webpack-dev-server-relative/src/relative-url.cy.jsx index b47c72bea025..1429f4367dd4 100644 --- a/system-tests/projects/webpack-dev-server-relative/src/relative-url.cy.jsx +++ b/system-tests/projects/webpack-dev-server-relative/src/relative-url.cy.jsx @@ -1,5 +1,5 @@ import React from 'react' -import { mount } from 'cypress/react18' +import { mount } from 'cypress/react' describe('webpack-dev-server', () => { it('image with relative path should load', () => { diff --git a/system-tests/projects/webpack5_wds4-react/src/App.cy.jsx b/system-tests/projects/webpack5_wds4-react/src/App.cy.jsx index df11cbb62b75..523c026f0797 100644 --- a/system-tests/projects/webpack5_wds4-react/src/App.cy.jsx +++ b/system-tests/projects/webpack5_wds4-react/src/App.cy.jsx @@ -1,6 +1,6 @@ import React from 'react' import { App } from './App' -import { mount } from 'cypress/react18' +import { mount } from 'cypress/react' it('renders hello world', () => { mount() diff --git a/system-tests/projects/webpack5_wds5-react/src/App.cy.jsx b/system-tests/projects/webpack5_wds5-react/src/App.cy.jsx index df11cbb62b75..523c026f0797 100644 --- a/system-tests/projects/webpack5_wds5-react/src/App.cy.jsx +++ b/system-tests/projects/webpack5_wds5-react/src/App.cy.jsx @@ -1,6 +1,6 @@ import React from 'react' import { App } from './App' -import { mount } from 'cypress/react18' +import { mount } from 'cypress/react' it('renders hello world', () => { mount() diff --git a/system-tests/test/component_testing_spec.ts b/system-tests/test/component_testing_spec.ts index 82bb5a1e7a0d..9644f3d94968 100644 --- a/system-tests/test/component_testing_spec.ts +++ b/system-tests/test/component_testing_spec.ts @@ -47,7 +47,7 @@ describe(`React major versions with Vite`, function () { return systemTests.exec(this, { project: `react${majorVersion}`, configFile: 'cypress-vite-default.config.ts', - spec: 'src/App.cy.jsx,src/Unmount.cy.jsx,src/UsingLegacyMount.cy.jsx,src/Rerendering.cy.jsx,src/mount.cy.jsx', + spec: 'src/App.cy.jsx,src/Unmount.cy.jsx,src/Rerendering.cy.jsx,src/mount.cy.jsx', testingType: 'component', browser: 'chrome', snapshot: true, @@ -65,7 +65,7 @@ describe(`React major versions with Webpack`, function () { return systemTests.exec(this, { project: `react${majorVersion}`, configFile: 'cypress-webpack.config.ts', - spec: 'src/App.cy.jsx,src/Unmount.cy.jsx,src/UsingLegacyMount.cy.jsx,src/Rerendering.cy.jsx,src/mount.cy.jsx', + spec: 'src/App.cy.jsx,src/Unmount.cy.jsx,src/Rerendering.cy.jsx,src/mount.cy.jsx', testingType: 'component', browser: 'chrome', snapshot: true, diff --git a/yarn.lock b/yarn.lock index 4c8695e5279a..10224f4b4ffc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1562,10 +1562,10 @@ dependencies: "@babel/types" "^7.24.7" -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.24.6", "@babel/helper-plugin-utils@^7.24.7", "@babel/helper-plugin-utils@^7.24.8", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": - version "7.24.8" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz#94ee67e8ec0e5d44ea7baeb51e571bd26af07878" - integrity sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg== +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.24.7", "@babel/helper-plugin-utils@^7.24.8", "@babel/helper-plugin-utils@^7.25.9", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.25.9" + resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz#9cbdd63a9443a2c92a725cca7ebca12cc8dd9f46" + integrity sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw== "@babel/helper-remap-async-to-generator@^7.24.7", "@babel/helper-remap-async-to-generator@^7.25.0": version "7.25.0" @@ -2229,19 +2229,19 @@ dependencies: "@babel/plugin-transform-react-jsx" "^7.24.7" -"@babel/plugin-transform-react-jsx-self@^7.24.5": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.24.6.tgz#4fa4870d594d6840d724d2006d0f98b19be6f502" - integrity sha512-FfZfHXtQ5jYPQsCRyLpOv2GeLIIJhs8aydpNh39vRDjhD411XcfWDni5i7OjP/Rs8GAtTn7sWFFELJSHqkIxYg== +"@babel/plugin-transform-react-jsx-self@^7.24.7": + version "7.25.9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.9.tgz#c0b6cae9c1b73967f7f9eb2fca9536ba2fad2858" + integrity sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg== dependencies: - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-react-jsx-source@^7.24.1": - version "7.24.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.24.6.tgz#4e1503f24ca5fccb1fc7f20c57426899d5ce5c1f" - integrity sha512-BQTBCXmFRreU3oTUXcGKuPOfXAGb1liNY4AvvFKsOBAJ89RKcTsIrSsnMYkj59fNa66OFKnSa4AJZfy5Y4B9WA== +"@babel/plugin-transform-react-jsx-source@^7.24.7": + version "7.25.9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.9.tgz#4c6b8daa520b5f155b5fb55547d7c9fa91417503" + integrity sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg== dependencies: - "@babel/helper-plugin-utils" "^7.24.6" + "@babel/helper-plugin-utils" "^7.25.9" "@babel/plugin-transform-react-jsx@^7.0.0", "@babel/plugin-transform-react-jsx@^7.24.7": version "7.25.2" @@ -6231,10 +6231,10 @@ tslib "^2.0.0" warning "^4.0.3" -"@remix-run/router@1.5.0": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.5.0.tgz#57618e57942a5f0131374a9fdb0167e25a117fdc" - integrity sha512-bkUDCp8o1MvFO+qxkODcbhSqRa6P2GXgrGZVpt0dCXNW2HCSCqYI0ZoAqEOSAjRWmmlKcYgFvN4B4S+zo/f8kg== +"@remix-run/router@1.21.0": + version "1.21.0" + resolved "https://registry.npmjs.org/@remix-run/router/-/router-1.21.0.tgz#c65ae4262bdcfe415dbd4f64ec87676e4a56e2b5" + integrity sha512-xfSkCAchbdG5PnbrKqFWwia4Bi61nH+wm8wLEqfHDyp7Y3dZzgqS2itV8i4gAq9pC2HsTpwyBC6Ds8VHZ96JlA== "@rollup/plugin-commonjs@^17.1.0": version "17.1.0" @@ -8195,13 +8195,6 @@ resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c" integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA== -"@types/react-dom@17.0.25": - version "17.0.25" - resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.25.tgz#e0e5b3571e1069625b3a3da2b279379aa33a0cb5" - integrity sha512-urx7A7UxkZQmThYA4So0NelOVjx3V4rNFVJwp0WZlbIK5eM4rNJDiN3R/E9ix0MBh6kAEojk/9YL+Te6D9zHNA== - dependencies: - "@types/react" "^17" - "@types/react-dom@18.3.1": version "18.3.1" resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.1.tgz#1e4654c08a9cdcfb6594c780ac59b55aad42fe07" @@ -8217,15 +8210,6 @@ "@types/prop-types" "*" csstype "^3.0.2" -"@types/react@17.0.83", "@types/react@^17": - version "17.0.83" - resolved "https://registry.npmjs.org/@types/react/-/react-17.0.83.tgz#b477c56387b74279281149dcf5ba2a1e2216d131" - integrity sha512-l0m4ArKJvmFtR4e8UmKrj1pB4tUgOhJITf+mADyF/p69Ts1YAR/E+G9XEM0mHXKVRa1dQNHseyyDNzeuAXfXQw== - dependencies: - "@types/prop-types" "*" - "@types/scheduler" "^0.16" - csstype "^3.0.2" - "@types/react@^16": version "16.14.62" resolved "https://registry.npmjs.org/@types/react/-/react-16.14.62.tgz#449e4e81caaf132d0c2c390644e577702db1dd9e" @@ -8295,12 +8279,7 @@ resolved "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz#ce5ace04cfeabe7ef87c0091e50752e36707deff" integrity sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A== -"@types/semver@7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.0.tgz#591c1ce3a702c45ee15f47a42ade72c2fd78978a" - integrity sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw== - -"@types/semver@^7.5.0": +"@types/semver@7.5.8", "@types/semver@^7.5.0": version "7.5.8" resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.8.tgz#8268a8c57a3e4abd25c165ecd36237db7948a55e" integrity sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ== @@ -8770,14 +8749,14 @@ regenerator-runtime "^0.14.1" systemjs "^6.15.1" -"@vitejs/plugin-react@4.3.0": - version "4.3.0" - resolved "https://registry.yarnpkg.com/@vitejs/plugin-react/-/plugin-react-4.3.0.tgz#f20ec2369a92d8abaaefa60da8b7157819d20481" - integrity sha512-KcEbMsn4Dpk+LIbHMj7gDPRKaTMStxxWRkRmxsg/jVdFdJCZWt1SchZcf0M4t8lIKdwwMsEyzhrcOXRrDPtOBw== +"@vitejs/plugin-react@4.3.3": + version "4.3.3" + resolved "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.3.tgz#28301ac6d7aaf20b73a418ee5c65b05519b4836c" + integrity sha512-NooDe9GpHGqNns1i8XDERg0Vsg5SSYRhRxxyTGogUdkdNt47jal+fbuYi+Yfq6pzRCKXyoPcWisfxE6RIM3GKA== dependencies: - "@babel/core" "^7.24.5" - "@babel/plugin-transform-react-jsx-self" "^7.24.5" - "@babel/plugin-transform-react-jsx-source" "^7.24.1" + "@babel/core" "^7.25.2" + "@babel/plugin-transform-react-jsx-self" "^7.24.7" + "@babel/plugin-transform-react-jsx-source" "^7.24.7" "@types/babel__core" "^7.20.5" react-refresh "^0.14.2" @@ -10624,7 +10603,7 @@ axios@0.21.2: dependencies: follow-redirects "^1.14.0" -axios@^1.7.4: +axios@1.7.7, axios@^1.7.4: version "1.7.7" resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.7.tgz#2f554296f9892a72ac8d8e4c5b79c14a91d0a47f" integrity sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q== @@ -22513,7 +22492,7 @@ mobx@6.13.5: resolved "https://registry.npmjs.org/mobx/-/mobx-6.13.5.tgz#957d9df88c7f8b4baa7c6f8bdcb6d68b432a6ed5" integrity sha512-/HTWzW2s8J1Gqt+WmUj5Y0mddZk+LInejADc79NJadrWla3rHzmRHki/mnEUH1AvOmbNTZ1BRbKxr8DSgfdjMA== -"mocha-7.0.1@npm:mocha@7.0.1": +"mocha-7.0.1@npm:mocha@7.0.1", mocha@7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/mocha/-/mocha-7.0.1.tgz#276186d35a4852f6249808c6dd4a1376cbf6c6ce" integrity sha512-9eWmWTdHLXh72rGrdZjNbG3aa1/3NRPpul1z0D979QpEnFdCG0Q5tv834N+94QEN2cysfV72YocQ3fn87s70fg== @@ -22630,36 +22609,6 @@ mocha@6.2.2: yargs-parser "13.1.1" yargs-unparser "1.6.0" -mocha@7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-7.0.1.tgz#276186d35a4852f6249808c6dd4a1376cbf6c6ce" - integrity sha512-9eWmWTdHLXh72rGrdZjNbG3aa1/3NRPpul1z0D979QpEnFdCG0Q5tv834N+94QEN2cysfV72YocQ3fn87s70fg== - dependencies: - ansi-colors "3.2.3" - browser-stdout "1.3.1" - chokidar "3.3.0" - debug "3.2.6" - diff "3.5.0" - escape-string-regexp "1.0.5" - find-up "3.0.0" - glob "7.1.3" - growl "1.10.5" - he "1.2.0" - js-yaml "3.13.1" - log-symbols "2.2.0" - minimatch "3.0.4" - mkdirp "0.5.1" - ms "2.1.1" - node-environment-flags "1.0.6" - object.assign "4.1.0" - strip-json-comments "2.0.1" - supports-color "6.0.0" - which "1.3.1" - wide-align "1.1.3" - yargs "13.3.0" - yargs-parser "13.1.1" - yargs-unparser "1.6.0" - mocha@7.1.0: version "7.1.0" resolved "https://registry.yarnpkg.com/mocha/-/mocha-7.1.0.tgz#c784f579ad0904d29229ad6cb1e2514e4db7d249" @@ -25908,7 +25857,7 @@ prop-types@15.7.2: object-assign "^4.1.1" react-is "^16.8.1" -prop-types@^15.5.10, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2: +prop-types@15.8.1, prop-types@^15.5.10, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2: version "15.8.1" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== @@ -26335,25 +26284,6 @@ react-docgen@6.0.4: object-assign "^4.1.1" prop-types "^15.6.0" -react-dom@16.8.6: - version "16.8.6" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.8.6.tgz#71d6303f631e8b0097f56165ef608f051ff6e10f" - integrity sha512-1nL7PIq9LTL3fthPqwkvr2zY7phIPjYrT0jp4HjyEQrEROnw4dG41VVwi/wfoCneoleqrNX7iAD+pXebJZwrwA== - dependencies: - loose-envify "^1.1.0" - object-assign "^4.1.1" - prop-types "^15.6.2" - scheduler "^0.13.6" - -react-dom@17.0.2, react-dom@^17.0.2: - version "17.0.2" - resolved "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23" - integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA== - dependencies: - loose-envify "^1.1.0" - object-assign "^4.1.1" - scheduler "^0.20.2" - react-dom@18.3.1: version "18.3.1" resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz#c2265d79511b57d479b3dd3fdfa51536494c5cb4" @@ -26423,20 +26353,20 @@ react-remove-scroll@^2.3.0: use-callback-ref "^1.2.3" use-sidecar "^1.0.1" -react-router-dom@6.10.0: - version "6.10.0" - resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.10.0.tgz#090ddc5c84dc41b583ce08468c4007c84245f61f" - integrity sha512-E5dfxRPuXKJqzwSe/qGcqdwa18QiWC6f3H3cWXM24qj4N0/beCIf/CWTipop2xm7mR0RCS99NnaqPNjHtrAzCg== +react-router-dom@6.28.0: + version "6.28.0" + resolved "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.28.0.tgz#f73ebb3490e59ac9f299377062ad1d10a9f579e6" + integrity sha512-kQ7Unsl5YdyOltsPGl31zOjLrDv+m2VcIEcIHqYYD3Lp0UppLjrzcfJqDJwXxFw3TH/yvapbnUvPlAj7Kx5nbg== dependencies: - "@remix-run/router" "1.5.0" - react-router "6.10.0" + "@remix-run/router" "1.21.0" + react-router "6.28.0" -react-router@6.10.0: - version "6.10.0" - resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.10.0.tgz#230f824fde9dd0270781b5cb497912de32c0a971" - integrity sha512-Nrg0BWpQqrC3ZFFkyewrflCud9dio9ME3ojHCF/WLsprJVzkq3q3UeEhMCAW1dobjeGbWgjNn/PVF6m46ANxXQ== +react-router@6.28.0: + version "6.28.0" + resolved "https://registry.npmjs.org/react-router/-/react-router-6.28.0.tgz#29247c86d7ba901d7e5a13aa79a96723c3e59d0d" + integrity sha512-HrYdIFqdrnhDw0PqG/AKjAqEqM7AvxCz0DQ4h2W8k6nqmc5uRBYDag0SBxx9iYz5G8gnuNVLzUe13wl9eAsXXg== dependencies: - "@remix-run/router" "1.5.0" + "@remix-run/router" "1.21.0" react-style-singleton@^2.1.0: version "2.1.1" @@ -26457,24 +26387,6 @@ react-test-renderer@^16.0.0-0: react-is "^16.8.6" scheduler "^0.19.1" -react@16.8.6: - version "16.8.6" - resolved "https://registry.yarnpkg.com/react/-/react-16.8.6.tgz#ad6c3a9614fd3a4e9ef51117f54d888da01f2bbe" - integrity sha512-pC0uMkhLaHm11ZSJULfOBqV4tIZkx87ZLvbbQYunNixAAvjnC+snJCg0XQXn9VIsttVsbZP/H/ewzgsd5fxKXw== - dependencies: - loose-envify "^1.1.0" - object-assign "^4.1.1" - prop-types "^15.6.2" - scheduler "^0.13.6" - -react@17.0.2, react@^17.0.2: - version "17.0.2" - resolved "https://registry.npmjs.org/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037" - integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA== - dependencies: - loose-envify "^1.1.0" - object-assign "^4.1.1" - react@18.3.1: version "18.3.1" resolved "https://registry.npmjs.org/react/-/react-18.3.1.tgz#49ab892009c53933625bd16b2533fc754cab2891" @@ -27597,14 +27509,6 @@ sax@>=0.6.0, sax@^1.2.4: resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== -scheduler@^0.13.6: - version "0.13.6" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.13.6.tgz#466a4ec332467b31a91b9bf74e5347072e4cd889" - integrity sha512-IWnObHt413ucAYKsD9J1QShUKkbKLQQHdxRyw73sw4FN26iWr3DY/H34xGPe4nmL1DwXyWmSWmMrA9TfQbE/XQ== - dependencies: - loose-envify "^1.1.0" - object-assign "^4.1.1" - scheduler@^0.19.1: version "0.19.1" resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.19.1.tgz#4f3e2ed2c1a7d65681f4c854fa8c5a1ccb40f196" @@ -27613,14 +27517,6 @@ scheduler@^0.19.1: loose-envify "^1.1.0" object-assign "^4.1.1" -scheduler@^0.20.2: - version "0.20.2" - resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91" - integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ== - dependencies: - loose-envify "^1.1.0" - object-assign "^4.1.1" - scheduler@^0.23.2: version "0.23.2" resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz#414ba64a3b282892e944cf2108ecc078d115cdc3" @@ -29282,7 +29178,7 @@ string-template@~0.2.1: resolved "https://registry.yarnpkg.com/string-template/-/string-template-0.2.1.tgz#42932e598a352d01fc22ec3367d9d84eec6c9add" integrity sha1-QpMuWYo1LQH8IuwzZ9nYTuxsmt0= -"string-width-cjs@npm:string-width@^4.2.0": +"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -29308,15 +29204,6 @@ string-width@^1.0.1, string-width@^1.0.2: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - string-width@^3.0.0, string-width@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" @@ -29427,7 +29314,7 @@ stringify-object@^3.0.0, stringify-object@^3.3.0: is-obj "^1.0.1" is-regexp "^1.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@6.0.1, strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -29448,13 +29335,6 @@ strip-ansi@5.2.0, strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: dependencies: ansi-regex "^4.1.0" -strip-ansi@6.0.1, strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" @@ -31785,7 +31665,7 @@ vite@5.2.11: optionalDependencies: fsevents "~2.3.3" -vite@^5.0.0: +vite@5.4.10, vite@^5.0.0: version "5.4.10" resolved "https://registry.npmjs.org/vite/-/vite-5.4.10.tgz#d358a7bd8beda6cf0f3b7a450a8c7693a4f80c18" integrity sha512-1hvaPshuPUtxeQ0hsVH3Mud0ZanOLwVTneA1EgbAM5LhaZEqyPWGRQ7BtaMvUrTDeEaC8pxtj6a6jku3x4z6SQ== @@ -32459,7 +32339,7 @@ workerpool@6.2.0: resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.0.tgz#827d93c9ba23ee2019c3ffaff5c27fccea289e8b" integrity sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -32502,15 +32382,6 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^8.0.1, wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" From 90da84a3b556a58952cc654b6a374f7dfa9b7707 Mon Sep 17 00:00:00 2001 From: AtofStryker Date: Fri, 15 Nov 2024 11:28:11 -0500 Subject: [PATCH 2/2] update tests / suggestions from code review [run ci] --- .../cypress/component/advanced/hooks/counter2-with-hooks.jsx | 2 +- npm/react/cypress/component/advanced/mocking-axios/1-users.jsx | 1 - .../cypress/component/advanced/mocking-axios/2-users-api.jsx | 1 - .../cypress/component/advanced/renderless/mouse-movement.jsx | 2 +- .../cypress/component/advanced/set-timeout-example/App.jsx | 2 +- .../component/advanced/set-timeout-example/LoadingIndicator.jsx | 2 +- 6 files changed, 4 insertions(+), 6 deletions(-) diff --git a/npm/react/cypress/component/advanced/hooks/counter2-with-hooks.jsx b/npm/react/cypress/component/advanced/hooks/counter2-with-hooks.jsx index 8d12775ee3c6..12fee25c14a3 100644 --- a/npm/react/cypress/component/advanced/hooks/counter2-with-hooks.jsx +++ b/npm/react/cypress/component/advanced/hooks/counter2-with-hooks.jsx @@ -6,7 +6,7 @@ export default function Counter2WithHooks () { useEffect(() => { document.title = `You clicked ${count} times` - }) + }, [count]) return (
    diff --git a/npm/react/cypress/component/advanced/mocking-axios/1-users.jsx b/npm/react/cypress/component/advanced/mocking-axios/1-users.jsx index 0e896fa1d0ed..4286947f6674 100644 --- a/npm/react/cypress/component/advanced/mocking-axios/1-users.jsx +++ b/npm/react/cypress/component/advanced/mocking-axios/1-users.jsx @@ -8,7 +8,6 @@ export function Users () { const getUsers = async () => { const response = await axios.get('https://jsonplaceholder.cypress.io/users?_limit=3') - // JSON responses are automatically parsed. setUsers(response.data) } diff --git a/npm/react/cypress/component/advanced/mocking-axios/2-users-api.jsx b/npm/react/cypress/component/advanced/mocking-axios/2-users-api.jsx index 96fcbc13c075..f8d2274fdf7b 100644 --- a/npm/react/cypress/component/advanced/mocking-axios/2-users-api.jsx +++ b/npm/react/cypress/component/advanced/mocking-axios/2-users-api.jsx @@ -8,7 +8,6 @@ export function Users () { const getUsers = async () => { console.log({ axiosApi }) const response = await axiosApi.get('https://jsonplaceholder.cypress.io/users?_limit=3') - // JSON responses are automatically parsed. setUsers(response.data) } diff --git a/npm/react/cypress/component/advanced/renderless/mouse-movement.jsx b/npm/react/cypress/component/advanced/renderless/mouse-movement.jsx index 609337969ec5..7782e8f44d69 100644 --- a/npm/react/cypress/component/advanced/renderless/mouse-movement.jsx +++ b/npm/react/cypress/component/advanced/renderless/mouse-movement.jsx @@ -36,7 +36,7 @@ export default function MouseMovement ({ onMoved }) { clearTimeout(timer) setTimer(undefined) } - }) + }, []) return null } diff --git a/npm/react/cypress/component/advanced/set-timeout-example/App.jsx b/npm/react/cypress/component/advanced/set-timeout-example/App.jsx index 6346e91ba177..c0cd7c76af93 100644 --- a/npm/react/cypress/component/advanced/set-timeout-example/App.jsx +++ b/npm/react/cypress/component/advanced/set-timeout-example/App.jsx @@ -12,7 +12,7 @@ function App () { return () => { clearTimeout(_timer) } - }) + }, []) return (
    diff --git a/npm/react/cypress/component/advanced/set-timeout-example/LoadingIndicator.jsx b/npm/react/cypress/component/advanced/set-timeout-example/LoadingIndicator.jsx index b5efe7a250d9..f4a57d7431c6 100644 --- a/npm/react/cypress/component/advanced/set-timeout-example/LoadingIndicator.jsx +++ b/npm/react/cypress/component/advanced/set-timeout-example/LoadingIndicator.jsx @@ -12,7 +12,7 @@ export default function LoadingIndicator ({ isLoading, children }) { return () => { clearTimeout(_delayTimer) } - }) + }, []) if (isLoading) { if (!isPastDelay) {