Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 30 additions & 26 deletions __e2e__/app.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -202,72 +202,76 @@ describe('Application launch', () => {
});

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

let currentInstance = 'Autoselect instances'; // Default instance
const wait = () => delay(750);
const selectInstance = async (instance) => {
await mainWindow.click(`//div[text()="${currentInstance}"]`);
let el = mainWindow.locator(`//div[text()="${currentInstance}"]`);
expect(await el.isVisible()).toBeTruthy();
await el.click({ force: true });
await wait();
currentInstance = instance;
await mainWindow.click(`//div[text()="${instance}"]`);
el = mainWindow.locator(`//div[text()="${instance}"]`);
expect(await el.isVisible()).toBeTruthy();
await el.click({ force: true });
await wait();
};
const commit = async () => {
await mainWindow.click('//div[text()="Commit"]');
await mainWindow.click('//button[text()="Commit"]', { force: true });
await wait();
};

const expectActions = {
'Redux store instance 1': {
expt: [
/@@INIT/,
/TEST_PASS_FOR_REDUX_STORE_1/,
/SHOW_FOR_REDUX_STORE_1/,
'@@INIT',
'TEST_PASS_FOR_REDUX_STORE_1',
'SHOW_FOR_REDUX_STORE_1',
],
notExpt: [/NOT_SHOW_FOR_REDUX_STORE_1/, /TEST_PASS_FOR_REDUX_STORE_2/],
notExpt: ['NOT_SHOW_FOR_REDUX_STORE_1', 'TEST_PASS_FOR_REDUX_STORE_2'],
},
'Redux store instance 2': {
expt: [/@@INIT/, /TEST_PASS_FOR_REDUX_STORE_2/],
expt: ['@@INIT', 'TEST_PASS_FOR_REDUX_STORE_2'],
notExpt: [
/TEST_PASS_FOR_REDUX_STORE_1/,
/NOT_SHOW_1_FOR_REDUX_STORE_2/,
/NOT_SHOW_2_FOR_REDUX_STORE_2/,
/NOT_SHOW_3_FOR_REDUX_STORE_2/,
'TEST_PASS_FOR_REDUX_STORE_1',
'NOT_SHOW_1_FOR_REDUX_STORE_2',
'NOT_SHOW_2_FOR_REDUX_STORE_2',
'NOT_SHOW_3_FOR_REDUX_STORE_2',
],
},
'MobX store instance 1': {
expt: [/@@INIT/, /testPassForMobXStore1/],
notExpt: [/TEST_PASS_FOR_REDUX_STORE_2/],
expt: ['@@INIT', 'testPassForMobXStore1'],
notExpt: ['TEST_PASS_FOR_REDUX_STORE_2'],
},
'MobX store instance 2': {
expt: [/@@INIT/, /testPassForMobXStore2/],
notExpt: [/testPassForMobXStore1/],
expt: ['@@INIT', 'testPassForMobXStore2'],
notExpt: ['testPassForMobXStore1'],
},
'RemoteDev store instance 1': {
expt: [/@@redux\/INIT/, /TEST_PASS_FOR_REMOTEDEV_STORE_1/],
notExpt: [/testPassForMobXStore2/],
expt: ['@@redux/INIT', 'TEST_PASS_FOR_REMOTEDEV_STORE_1'],
notExpt: ['testPassForMobXStore2'],
},
};

const runExpectActions = (name, val) => {
const runExpectActions = async (name) => {
const { expt, notExpt } = expectActions[name];

for (const action of expt) {
expect(val).toMatch(action);
const el = await mainWindow.locator('div').filter({ hasText: action }).first();
expect(await el.isVisible()).toBeTruthy();
}
for (const action of notExpt) {
expect(val).not.toMatch(action);
const el = await mainWindow.locator('div').filter({ hasText: action }).first();
expect(await el.isVisible()).toBeFalsy();
}
};

const checkInstance = async (name) => {
await selectInstance(name);
const val = await mainWindow.textContent('//div[contains(@class, "actionListRows-")]');
runExpectActions(name, val);
await runExpectActions(name);
await commit();
};

Expand Down
2 changes: 1 addition & 1 deletion app/containers/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import * as debuggerActions from '../actions/debugger';
import * as settingActions from '../actions/setting';
import ReduxDevTools from './ReduxDevTools';
import ReduxDevTools from './redux/DevTools';
import ReactInspector from './ReactInspector';
import FormInput from '../components/FormInput';
import Draggable from '../components/Draggable';
Expand Down
2 changes: 1 addition & 1 deletion app/containers/ReactInspector.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const styles = {
waiting: {
height: '100%',
display: 'flex',
webkitUserSelect: 'none',
WebkitUserSelect: 'none',
textAlign: 'center',
color: '#aaa',
justifyContent: 'center',
Expand Down
143 changes: 0 additions & 143 deletions app/containers/ReduxDevTools.js

This file was deleted.

41 changes: 41 additions & 0 deletions app/containers/redux/DevTools.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { Container, Notification } from '@redux-devtools/ui';
import { clearNotification } from '@redux-devtools/app/lib/esm/actions';
import Actions from '@redux-devtools/app/lib/esm/containers/Actions';
import Settings from './Settings';
import Header from './Header';

const App = () => {
const section = useSelector(state => state.section);
const theme = useSelector(state => state.theme);
const notification = useSelector(state => state.notification);

const dispatch = useDispatch();

let body;
switch (section) {
case 'Settings':
body = <Settings />;
break;
default:
body = <Actions />;
}

return (
<Container themeData={theme}>
<Header section={section} />
{body}
{notification && (
<Notification
type={notification.type}
onClose={() => dispatch(clearNotification())}
>
{notification.message}
</Notification>
)}
</Container>
);
};

export default App;
59 changes: 59 additions & 0 deletions app/containers/redux/Header.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import React, { useCallback } from 'react';
import PropTypes from 'prop-types';
import { useDispatch } from 'react-redux';
import { Tabs, Toolbar, Button, Divider } from '@redux-devtools/ui';
import { GoBook } from 'react-icons/go';
import styled from 'styled-components';
import { changeSection } from '@redux-devtools/app/lib/esm/actions';
import { shell } from 'electron';

const WindowDraggable = styled.div`
display: flex;
flex: 1;
height: 100%;
-webkit-app-region: drag;
-webkit-user-select: none;
`;

const tabs = [{ name: 'Actions' }, { name: 'Settings' }];

const Header = (props) => {
const { section } = props;

const dispatch = useDispatch();

const handleChangeSection = useCallback(
(sec) => dispatch(changeSection(sec)),
[dispatch, changeSection],
);

const openHelp = useCallback(() => shell.openExternal('https://goo.gl/SHU4yL'), []);

return (
<Toolbar compact noBorder borderPosition="bottom">
<Tabs
main
collapsible
tabs={tabs}
onClick={handleChangeSection}
selected={section || 'Actions'}
style={{ flex: 'unset' }}
/>
<WindowDraggable />
<Divider />
<Button
title="Documentation"
tooltipPosition="bottom"
onClick={openHelp}
>
<GoBook />
</Button>
</Toolbar>
);
};

Header.propTypes = {
section: PropTypes.string,
};

export default Header;
26 changes: 26 additions & 0 deletions app/containers/redux/Settings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/* eslint-disable import/no-named-as-default */
import React, { Component } from 'react';
import Tabs from '@redux-devtools/ui/lib/esm/Tabs/Tabs';
import Themes from '@redux-devtools/app/lib/esm/components/Settings/Themes';

export default class Settings extends Component {
state = { selected: 'Themes' };

tabs = [
{ name: 'Themes', component: Themes },
];

handleSelect = (selected) => {
this.setState({ selected });
};

render() {
return (
<Tabs
tabs={this.tabs}
selected={this.state.selected}
onClick={this.handleSelect}
/>
);
}
}
Loading