Skip to content

Commit

Permalink
Migrate to React 18 (#1652)
Browse files Browse the repository at this point in the history
* Upgrade to React 18

* Broken test cases fixed

* Test with Kedro-viz as react component fix by enzyme to react-testing-library

* Removing cypress tests to observe effect

Signed-off-by: mehdinv <[email protected]>

* Re-adding deleted shareable-urls cypress tests

Signed-off-by: mehdinv <[email protected]>

* Cypress test fix

* Cypress added back

* Whitespace removed

* Release note and comment added

* react-redux updated to latest

* Upgrading React testing-library to latest

---------

Signed-off-by: mehdinv <[email protected]>
Co-authored-by: Jitendra Gundaniya <[email protected]>
Co-authored-by: rashidakanchwala <[email protected]>
Co-authored-by: Jitendra Gundaniya <[email protected]>
  • Loading branch information
4 people authored Dec 12, 2023
1 parent b9b0a96 commit 8c9546e
Show file tree
Hide file tree
Showing 18 changed files with 14,448 additions and 18,214 deletions.
6 changes: 6 additions & 0 deletions RELEASE.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ Please follow the established format:
- Remove support for Python 3.7 (#1660)
- Adjust CLI to use 'kedro viz run' instead of 'kedro viz' (#1671)

# Release 7.0.0

## Major features and improvements

- Bump minimum version of React from 17.0.2 to 18.2.0. (#1652)

# Release 6.7.0

## Bug fixes and other changes
Expand Down
32,497 changes: 14,355 additions & 18,142 deletions package-lock.json

Large diffs are not rendered by default.

28 changes: 17 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"@graphql-tools/schema": "7.1.5",
"@mui/icons-material": "^5.11.9",
"@mui/material": "^5.11.10",
"@mui/styles": "^5.11.9",
"@mui/system": "^5.14.18",
"@mui/x-tree-view": "^6.17.0",
"batching-toposort": "^1.2.0",
"classnames": "^2.3.1",
Expand Down Expand Up @@ -78,10 +78,9 @@
"react-custom-scrollbars-2": "^4.5.0",
"react-json-view": "^1.21.3",
"react-plotly.js": "^2.5.1",
"react-redux": "^7.2.6",
"react-redux": "^8.1.3",
"react-router": "^5.2.1",
"react-router-dom": "^5.3.0",
"react-test-renderer": "^17.0.2",
"redux": "^4.1.2",
"redux-mock-store": "^1.5.4",
"redux-thunk": "^2.4.1",
Expand All @@ -93,19 +92,26 @@
"uuid": "^9.0.0",
"what-input": "^5.2.10"
},
"overrides": {
"react-json-view": {
"react": "$react",
"react-dom": "$react-dom",
"react-json-view": "^1.21.3"
}
},
"peerDependencies": {
"react": "^17.0.2",
"react-dom": "^17.0.2"
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@babel/cli": "^7.14.5",
"@babel/core": "^7.14.6",
"@babel/plugin-proposal-class-properties": "^7.14.5",
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^11.2.7",
"@testing-library/user-event": "^12.8.3",
"@wojtekmaj/enzyme-adapter-react-17": "^0.8.0",
"@cfaester/enzyme-adapter-react-18": "^0.7.1",
"@testing-library/jest-dom": "^6.1.4",
"@testing-library/react": "^14.1.2",
"@testing-library/user-event": "^14.5.1",
"babel-plugin-transform-remove-imports": "^1.7.0",
"canvas": "^2.7.0",
"cross-env": "7.0.3",
Expand All @@ -120,8 +126,8 @@
"npm-run-all": "^4.1.5",
"postcss-loader": "^4.3.0",
"prettier": "^2.3.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-error-overlay": "^6.0.9",
"react-scripts": "^4.0.3",
"sass": "^1.54.4",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import Accordion from '.';
import Adapter from '@wojtekmaj/enzyme-adapter-react-17';
import Adapter from '@cfaester/enzyme-adapter-react-18';
import { configure, mount, shallow } from 'enzyme';

configure({ adapter: new Adapter() });
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import RunDetailsModal from './index';
import Adapter from '@wojtekmaj/enzyme-adapter-react-17';
import Adapter from '@cfaester/enzyme-adapter-react-18';
import { configure } from 'enzyme';
import { waitFor } from '@testing-library/react';
import { ButtonTimeoutContext } from '../../../utils/button-timeout-context';
Expand Down Expand Up @@ -62,7 +62,9 @@ describe('RunDetailsModal', () => {

onClick.mockImplementation((visible) => [visible, setVisible]);

closeButton.simulate('click');
waitFor(() => {
closeButton.simulate('click');
});

expect(
wrapper.find(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { useState, useCallback, useContext, useEffect } from 'react';
import { flushSync } from 'react-dom';
import { connect } from 'react-redux';
import { CSVLink } from 'react-csv';

Expand Down Expand Up @@ -33,8 +34,11 @@ const RunExportModal = ({
};
});

setExportData(constructExportData(mergedRunsMetadata, runTrackingData));
handleClick();
// Require to opt-out of automatic batching in React 18
flushSync(() => {
setExportData(constructExportData(mergedRunsMetadata, runTrackingData));
handleClick();
});
}, [runMetadata, runTrackingData, handleClick, runsMetadata]);

// only if the component is visible first, then apply isSuccessful to show or hide modal
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import configureMockStore from 'redux-mock-store';
import RunExportModal from './index';
import Adapter from '@wojtekmaj/enzyme-adapter-react-17';
import Adapter from '@cfaester/enzyme-adapter-react-18';
import { configure } from 'enzyme';
import { render, screen } from '@testing-library/react';
import { ButtonTimeoutContext } from '../../../utils/button-timeout-context';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';
import configureMockStore from 'redux-mock-store';
import RunMetadata from '.';
import { runs } from '../../experiment-wrapper/mock-data';
import Adapter from '@wojtekmaj/enzyme-adapter-react-17';
import Adapter from '@cfaester/enzyme-adapter-react-18';
import { configure, mount } from 'enzyme';
import { setup } from '../../../utils/state.mock';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import configureMockStore from 'redux-mock-store';
import RunsListCard from '.';
import Adapter from '@wojtekmaj/enzyme-adapter-react-17';
import Adapter from '@cfaester/enzyme-adapter-react-18';
import { configure, mount } from 'enzyme';
import { HoverStateContext } from '../utils/hover-state-context';
import { setup } from '../../../utils/state.mock';
Expand Down
15 changes: 3 additions & 12 deletions src/components/node-list/node-list-tree.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import { connect } from 'react-redux';

import { makeStyles, withStyles } from '@mui/styles';
import { styled } from '@mui/system';
import { TreeView } from '@mui/x-tree-view';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import ChevronRightIcon from '@mui/icons-material/ChevronRight';
Expand All @@ -25,20 +25,15 @@ const GROUPED_NODES_DISPLAY_ORDER = {

// please note that this setup is unique for initialization of the material-ui tree,
// and setup is only used here and not anywhere else in the app.
const useStyles = makeStyles({
const StyledTreeView = styled(TreeView)({
root: {
height: 110,
flexGrow: 1,
maxWidth: 400,
},
padding: '0 0 0 20px',
});

const StyledTreeView = withStyles({
root: {
padding: '0 0 0 20px',
},
})(TreeView);

/**
* Return whether the given modular pipeline ID is on focus mode path, i.e.
* it's not the currently focused pipeline nor one of its children.
Expand Down Expand Up @@ -124,8 +119,6 @@ const TreeListProvider = ({
expanded,
onToggleNodeSelected,
}) => {
const classes = useStyles();

// render a leaf node in the modular pipelines tree
const renderLeafNode = (node) => {
const disabled =
Expand Down Expand Up @@ -220,7 +213,6 @@ const TreeListProvider = ({

return modularPipelinesSearchResult ? (
<StyledTreeView
className={classes.root}
expanded={Object.keys(modularPipelinesSearchResult)}
defaultCollapseIcon={<ExpandMoreIcon />}
defaultExpandIcon={<ChevronRightIcon />}
Expand All @@ -231,7 +223,6 @@ const TreeListProvider = ({
) : (
<StyledTreeView
expanded={expanded}
className={classes.root}
defaultCollapseIcon={<ExpandMoreIcon />}
defaultExpandIcon={<ChevronRightIcon />}
onNodeToggle={onItemExpandCollapseToggle}
Expand Down
2 changes: 1 addition & 1 deletion src/components/ui/search-bar/search-bar.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { shallow, configure } from 'enzyme';
import Adapter from '@wojtekmaj/enzyme-adapter-react-17';
import Adapter from '@cfaester/enzyme-adapter-react-18';
import SearchBar from './search-bar';

configure({ adapter: new Adapter() });
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { shallow, configure, mount } from 'enzyme';
import Adapter from '@wojtekmaj/enzyme-adapter-react-17';
import Adapter from '@cfaester/enzyme-adapter-react-18';

import SearchInput from './search-input';

Expand Down
2 changes: 1 addition & 1 deletion src/components/ui/switch/switch.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import Switch from './switch';
import Adapter from '@wojtekmaj/enzyme-adapter-react-17';
import Adapter from '@cfaester/enzyme-adapter-react-18';
import { configure, mount, shallow } from 'enzyme';

configure({ adapter: new Adapter() });
Expand Down
6 changes: 4 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { createRoot } from 'react-dom/client';
import KedroViz from './components/container';

ReactDOM.render(<KedroViz />, document.getElementById('root'));
const container = document.getElementById('root');
const root = createRoot(container);
root.render(<KedroViz />);
10 changes: 8 additions & 2 deletions src/setupTests.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
// Configure react-testing-library
// See https://create-react-app.dev/docs/running-tests/#option-2-react-testing-library
import '@testing-library/jest-dom/extend-expect';
import '@testing-library/jest-dom';

// Configure enzyme
// See https://create-react-app.dev/docs/running-tests/#srcsetuptestsjs
import { configure } from 'enzyme';
import Adapter from '@wojtekmaj/enzyme-adapter-react-17';
import Adapter from '@cfaester/enzyme-adapter-react-18';
import util from 'util';

// Require to run enzyme tests after upgrading to React 18
Object.defineProperty(global, 'TextEncoder', {
value: util.TextEncoder,
});

// Require to create jest using Plotly.js library
window.URL.createObjectURL = jest.fn();
Expand Down
38 changes: 16 additions & 22 deletions tools/test-lib/react-app/app.test.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,26 @@
import React from 'react';
import { configure, mount } from 'enzyme';
import Adapter from '@wojtekmaj/enzyme-adapter-react-17';
import { render, screen, fireEvent } from '@testing-library/react';
import App, { dataSources } from './app';

configure({ adapter: new Adapter() });

const keys = Object.keys(dataSources).filter((key) => key !== 'random');

describe('lib-test', () => {
test('renders without crashing', () => {
mount(<App />);
render(<App />);
});

/**
* Get the name of the first node in the NodeList, and check that it's
* included in the list of the node names in the dataset
* @param {object} wrapper App component mounted by Enzyme
* * @param {object} container App component mounted
* @param {string} key dataSources key: spaceflights/demo/random
*/
const testFirstNodeNameMatch = (wrapper, key) => {
const firstNodeName = wrapper
.find('.pipeline-nodelist__row')
.find('.pipeline-nodelist__row__text--tree')
.find('.pipeline-nodelist__row__label')
.first()
.text();
const testFirstNodeNameMatch = (container, key) => {
const firstNodeName = container
.querySelector('.pipeline-nodelist__row')
.querySelector('.pipeline-nodelist__row__text--tree')
.querySelector('.pipeline-nodelist__row__label')
.textContent;

const modularPipelinesTree = dataSources[key]().modular_pipelines;
const modularPipelineNames = Object.keys(modularPipelinesTree).map(
Expand All @@ -34,20 +30,18 @@ describe('lib-test', () => {
};

test.each(keys)(`uses %s dataset when provided as prop`, (key) => {
const wrapper = mount(<App initialData={key} />);
testFirstNodeNameMatch(wrapper, key);
const { container } = render(<App initialData={key} />);
testFirstNodeNameMatch(container, key);
});

test.each(keys)(
`updates to %s dataset when radio button triggers change`,
(key) => {
const wrapper = mount(<App />);
wrapper
.find('Radio')
.filter(`[value="${key}"]`)
.find('input')
.simulate('change');
testFirstNodeNameMatch(wrapper, key);
const { container } = render(<App />);

const radioInput = container.querySelector(`[value="${key}"]`);
fireEvent.click(radioInput, { target: { value: key } });
testFirstNodeNameMatch(container, key);
}
);
});
28 changes: 18 additions & 10 deletions tools/test-lib/react-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,41 +10,49 @@
"jest": {
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
"\\.(css|less)$": "<rootDir>/__mocks__/styleMock.js"
"\\.(css|less|scss)$": "<rootDir>/__mocks__/styleMock.js"
},
"transformIgnorePatterns": [
"/node_modules/(?!d3|d3-array|internmap|delaunator|robust-predicates)"
],
"setupFilesAfterEnv": [
"<rootDir>/jest.setup.js"
]
],
"testEnvironment": "jest-environment-jsdom-global"
},
"dependencies": {
"@quantumblack/kedro-viz": "file:kedro-viz.tgz",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router": "^6.3.0",
"react-router-dom": "^6.3.0"
},
"devDependencies": {
"@babel/core": "^7.10.5",
"@babel/preset-env": "^7.10.4",
"@babel/preset-react": "^7.10.4",
"@wojtekmaj/enzyme-adapter-react-17": "^0.8.0",
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^11.2.7",
"babel-loader": "^8.1.0",
"clean-webpack-plugin": "^3.0.0",
"css-loader": "^4.0.0",
"enzyme": "^3.11.0",
"html-webpack-plugin": "^4.3.0",
"jest": "^26.2.2",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"jest-environment-jsdom-global": "^4.0.0",
"style-loader": "^1.2.1",
"webpack": "^4.44.0",
"webpack-cli": "^3.3.12",
"webpack-dev-server": "^4.10.0"
"webpack": "^5.89.0",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^4.15.1"
},
"overrides": {
"jsdom": {
"tough-cookie": "4.0.0"
},
"react-json-view": {
"react": "$react",
"react-dom": "$react-dom",
"react-json-view": "^1.21.3"
}
}
}
Loading

0 comments on commit 8c9546e

Please sign in to comment.