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/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/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..bda0bcb3ed5f 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('deep.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..cef9f78f071e
--- /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'
+
+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 (
-
-
-
- Welcome to React
-
-
isLoading: {String(this.state.isLoading)}
-
- ahoy!
-
-
- )
- }
+ return (
+
+
+
+ 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 (
- this.setState({ value: this.props.value })}
- >
- {this.state.value}
-
- )
- }
+ return (
+ setValueAsState(valueAsProp)}>
+ {valueAsState}
+
+ )
}
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 (
+
+ {value}
+
+ )
+}
- 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 (
-
- {props.value}
-
+ <>
+ {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)}
-
-
+
+ jumpTo(move)}>{description}
+
)
- }
-}
+ })
-export class Game extends React.Component {
- render () {
- return (
-
-
-
-
-
-
{/* status */}
-
{/* TODO */}
-
+ return (
+
+ )
+}
+
+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 (
-
- {this.props.name}
-
- )
+ function handleClick () {
+ clickHandler(name)
}
+
+ return (
+
+ {name}
+
+ )
}
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 (
-
- {props.value}
+
+ {value}
)
}
-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 (
-
- this.jumpTo(move)}>{desc}
-
- )
- })
+ 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)} />
-
-
-
+
+ jumpTo(move)}>{description}
+
)
- }
-}
+ })
-// ========================================
-
-// ReactDOM.render( , document.getElementById('root'))
+ return (
+
+ )
+}
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 (
- alert('click')}>
- {this.props.value}
-
- )
- }
+export default function Square ({ value }) {
+ return (
+ alert('click')}>
+ {value}
+
+ )
}
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 (
- alert('click')}>
- {this.props.value}
-
- )
- }
+export default function Square ({ value }) {
+ return (
+ alert('click')}>
+ {value || null}
+
+ )
}
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 (
- this.setState({ value: 'X' })}>
- {this.state.value}
-
- )
- }
+ return (
+ setValue('X')}>
+ {value}
+
+ )
}
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 (
-
- {props.value}
+
+ {value}
)
}
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 bcbc6af49bdb..1a866514d967 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 38af5da9c35f..b0f037b039b8 100644
--- a/system-tests/__snapshots__/component_testing_spec.ts.js
+++ b/system-tests/__snapshots__/component_testing_spec.ts.js
@@ -7,10 +7,8 @@ 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 │
└────────────────────────────────────────────────────────────────────────────────────────────────┘
@@ -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,34 +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)
+ Running: Rerendering.cy.jsx (3 of 4)
re-render
@@ -127,7 +98,7 @@ exports['React major versions with Webpack executes all of the tests for React v
────────────────────────────────────────────────────────────────────────────────────────────────────
- Running: mount.cy.jsx (5 of 5)
+ Running: mount.cy.jsx (4 of 4)
mount
@@ -166,372 +137,11 @@ exports['React major versions with Webpack executes all of the tests for React v
├────────────────────────────────────────────────────────────────────────────────────────────────┤
│ ✔ 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)
-
-
- 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 - - -
+ ✔ 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 67553298baab..1c8b19731796 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1553,10 +1553,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"
@@ -2220,19 +2220,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"
@@ -6230,10 +6230,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"
@@ -8194,13 +8194,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"
@@ -8216,15 +8209,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"
@@ -8294,12 +8278,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==
@@ -8769,14 +8748,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"
@@ -10618,7 +10597,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==
@@ -22479,7 +22458,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==
@@ -22596,36 +22575,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"
@@ -25865,7 +25814,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==
@@ -26292,25 +26241,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"
@@ -26380,20 +26310,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"
@@ -26414,24 +26344,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"
@@ -27554,14 +27466,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"
@@ -27570,14 +27474,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"
@@ -29239,7 +29135,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==
@@ -29265,15 +29161,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"
@@ -29384,7 +29271,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==
@@ -29405,13 +29292,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"
@@ -31727,7 +31607,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==
@@ -32401,7 +32281,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==
@@ -32444,15 +32324,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"