Skip to content

Commit a1c272c

Browse files
authored
Upgrade redux-devtools to latest version (#781)
* Initial work of @redux-devtools/app upgrade * Add missing PersistGate * Fix lint errors * Add patches/@redux-devtools+inspector-monitor-trace-tab+1.0.0.patch * Add window dragable in header & custom buttons * Custom Settings (Remove connection tab) * Fix tabs style * Update docs/redux-devtools-integration.md * Update default instances state * Update E2E tests * Remove socketcluster-client alias * Cleanup
1 parent 39b0dd9 commit a1c272c

22 files changed

Lines changed: 2150 additions & 1400 deletions

__e2e__/app.spec.js

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -202,72 +202,76 @@ describe('Application launch', () => {
202202
});
203203

204204
it('should have @@INIT action on Redux DevTools', async () => {
205-
expect(
206-
await mainWindow.textContent('//div[contains(@class, "actionListRows-")]')
207-
).toMatch(/@@redux\/INIT/); // Last store is `RemoteDev store instance 1`
205+
const el = await mainWindow.locator('div').filter({ hasText: '@@redux/INIT' }).first();
206+
expect(await el.isVisible()).toBeTruthy(); // Last store is `RemoteDev store instance 1`
208207
});
209208

210209
let currentInstance = 'Autoselect instances'; // Default instance
211210
const wait = () => delay(750);
212211
const selectInstance = async (instance) => {
213-
await mainWindow.click(`//div[text()="${currentInstance}"]`);
212+
let el = mainWindow.locator(`//div[text()="${currentInstance}"]`);
213+
expect(await el.isVisible()).toBeTruthy();
214+
await el.click({ force: true });
214215
await wait();
215216
currentInstance = instance;
216-
await mainWindow.click(`//div[text()="${instance}"]`);
217+
el = mainWindow.locator(`//div[text()="${instance}"]`);
218+
expect(await el.isVisible()).toBeTruthy();
219+
await el.click({ force: true });
217220
await wait();
218221
};
219222
const commit = async () => {
220-
await mainWindow.click('//div[text()="Commit"]');
223+
await mainWindow.click('//button[text()="Commit"]', { force: true });
221224
await wait();
222225
};
223226

224227
const expectActions = {
225228
'Redux store instance 1': {
226229
expt: [
227-
/@@INIT/,
228-
/TEST_PASS_FOR_REDUX_STORE_1/,
229-
/SHOW_FOR_REDUX_STORE_1/,
230+
'@@INIT',
231+
'TEST_PASS_FOR_REDUX_STORE_1',
232+
'SHOW_FOR_REDUX_STORE_1',
230233
],
231-
notExpt: [/NOT_SHOW_FOR_REDUX_STORE_1/, /TEST_PASS_FOR_REDUX_STORE_2/],
234+
notExpt: ['NOT_SHOW_FOR_REDUX_STORE_1', 'TEST_PASS_FOR_REDUX_STORE_2'],
232235
},
233236
'Redux store instance 2': {
234-
expt: [/@@INIT/, /TEST_PASS_FOR_REDUX_STORE_2/],
237+
expt: ['@@INIT', 'TEST_PASS_FOR_REDUX_STORE_2'],
235238
notExpt: [
236-
/TEST_PASS_FOR_REDUX_STORE_1/,
237-
/NOT_SHOW_1_FOR_REDUX_STORE_2/,
238-
/NOT_SHOW_2_FOR_REDUX_STORE_2/,
239-
/NOT_SHOW_3_FOR_REDUX_STORE_2/,
239+
'TEST_PASS_FOR_REDUX_STORE_1',
240+
'NOT_SHOW_1_FOR_REDUX_STORE_2',
241+
'NOT_SHOW_2_FOR_REDUX_STORE_2',
242+
'NOT_SHOW_3_FOR_REDUX_STORE_2',
240243
],
241244
},
242245
'MobX store instance 1': {
243-
expt: [/@@INIT/, /testPassForMobXStore1/],
244-
notExpt: [/TEST_PASS_FOR_REDUX_STORE_2/],
246+
expt: ['@@INIT', 'testPassForMobXStore1'],
247+
notExpt: ['TEST_PASS_FOR_REDUX_STORE_2'],
245248
},
246249
'MobX store instance 2': {
247-
expt: [/@@INIT/, /testPassForMobXStore2/],
248-
notExpt: [/testPassForMobXStore1/],
250+
expt: ['@@INIT', 'testPassForMobXStore2'],
251+
notExpt: ['testPassForMobXStore1'],
249252
},
250253
'RemoteDev store instance 1': {
251-
expt: [/@@redux\/INIT/, /TEST_PASS_FOR_REMOTEDEV_STORE_1/],
252-
notExpt: [/testPassForMobXStore2/],
254+
expt: ['@@redux/INIT', 'TEST_PASS_FOR_REMOTEDEV_STORE_1'],
255+
notExpt: ['testPassForMobXStore2'],
253256
},
254257
};
255258

256-
const runExpectActions = (name, val) => {
259+
const runExpectActions = async (name) => {
257260
const { expt, notExpt } = expectActions[name];
258261

259262
for (const action of expt) {
260-
expect(val).toMatch(action);
263+
const el = await mainWindow.locator('div').filter({ hasText: action }).first();
264+
expect(await el.isVisible()).toBeTruthy();
261265
}
262266
for (const action of notExpt) {
263-
expect(val).not.toMatch(action);
267+
const el = await mainWindow.locator('div').filter({ hasText: action }).first();
268+
expect(await el.isVisible()).toBeFalsy();
264269
}
265270
};
266271

267272
const checkInstance = async (name) => {
268273
await selectInstance(name);
269-
const val = await mainWindow.textContent('//div[contains(@class, "actionListRows-")]');
270-
runExpectActions(name, val);
274+
await runExpectActions(name);
271275
await commit();
272276
};
273277

app/containers/App.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { bindActionCreators } from 'redux';
66
import { connect } from 'react-redux';
77
import * as debuggerActions from '../actions/debugger';
88
import * as settingActions from '../actions/setting';
9-
import ReduxDevTools from './ReduxDevTools';
9+
import ReduxDevTools from './redux/DevTools';
1010
import ReactInspector from './ReactInspector';
1111
import FormInput from '../components/FormInput';
1212
import Draggable from '../components/Draggable';

app/containers/ReactInspector.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const styles = {
2626
waiting: {
2727
height: '100%',
2828
display: 'flex',
29-
webkitUserSelect: 'none',
29+
WebkitUserSelect: 'none',
3030
textAlign: 'center',
3131
color: '#aaa',
3232
justifyContent: 'center',

app/containers/ReduxDevTools.js

Lines changed: 0 additions & 143 deletions
This file was deleted.

app/containers/redux/DevTools.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import React from 'react';
2+
import { useSelector, useDispatch } from 'react-redux';
3+
import { Container, Notification } from '@redux-devtools/ui';
4+
import { clearNotification } from '@redux-devtools/app/lib/esm/actions';
5+
import Actions from '@redux-devtools/app/lib/esm/containers/Actions';
6+
import Settings from './Settings';
7+
import Header from './Header';
8+
9+
const App = () => {
10+
const section = useSelector(state => state.section);
11+
const theme = useSelector(state => state.theme);
12+
const notification = useSelector(state => state.notification);
13+
14+
const dispatch = useDispatch();
15+
16+
let body;
17+
switch (section) {
18+
case 'Settings':
19+
body = <Settings />;
20+
break;
21+
default:
22+
body = <Actions />;
23+
}
24+
25+
return (
26+
<Container themeData={theme}>
27+
<Header section={section} />
28+
{body}
29+
{notification && (
30+
<Notification
31+
type={notification.type}
32+
onClose={() => dispatch(clearNotification())}
33+
>
34+
{notification.message}
35+
</Notification>
36+
)}
37+
</Container>
38+
);
39+
};
40+
41+
export default App;

app/containers/redux/Header.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import React, { useCallback } from 'react';
2+
import PropTypes from 'prop-types';
3+
import { useDispatch } from 'react-redux';
4+
import { Tabs, Toolbar, Button, Divider } from '@redux-devtools/ui';
5+
import { GoBook } from 'react-icons/go';
6+
import styled from 'styled-components';
7+
import { changeSection } from '@redux-devtools/app/lib/esm/actions';
8+
import { shell } from 'electron';
9+
10+
const WindowDraggable = styled.div`
11+
display: flex;
12+
flex: 1;
13+
height: 100%;
14+
-webkit-app-region: drag;
15+
-webkit-user-select: none;
16+
`;
17+
18+
const tabs = [{ name: 'Actions' }, { name: 'Settings' }];
19+
20+
const Header = (props) => {
21+
const { section } = props;
22+
23+
const dispatch = useDispatch();
24+
25+
const handleChangeSection = useCallback(
26+
(sec) => dispatch(changeSection(sec)),
27+
[dispatch, changeSection],
28+
);
29+
30+
const openHelp = useCallback(() => shell.openExternal('https://goo.gl/SHU4yL'), []);
31+
32+
return (
33+
<Toolbar compact noBorder borderPosition="bottom">
34+
<Tabs
35+
main
36+
collapsible
37+
tabs={tabs}
38+
onClick={handleChangeSection}
39+
selected={section || 'Actions'}
40+
style={{ flex: 'unset' }}
41+
/>
42+
<WindowDraggable />
43+
<Divider />
44+
<Button
45+
title="Documentation"
46+
tooltipPosition="bottom"
47+
onClick={openHelp}
48+
>
49+
<GoBook />
50+
</Button>
51+
</Toolbar>
52+
);
53+
};
54+
55+
Header.propTypes = {
56+
section: PropTypes.string,
57+
};
58+
59+
export default Header;

app/containers/redux/Settings.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/* eslint-disable import/no-named-as-default */
2+
import React, { Component } from 'react';
3+
import Tabs from '@redux-devtools/ui/lib/esm/Tabs/Tabs';
4+
import Themes from '@redux-devtools/app/lib/esm/components/Settings/Themes';
5+
6+
export default class Settings extends Component {
7+
state = { selected: 'Themes' };
8+
9+
tabs = [
10+
{ name: 'Themes', component: Themes },
11+
];
12+
13+
handleSelect = (selected) => {
14+
this.setState({ selected });
15+
};
16+
17+
render() {
18+
return (
19+
<Tabs
20+
tabs={this.tabs}
21+
selected={this.state.selected}
22+
onClick={this.handleSelect}
23+
/>
24+
);
25+
}
26+
}

0 commit comments

Comments
 (0)