2020-11-16 21:37:40 +03:00
|
|
|
import '@babel/polyfill';
|
2020-10-26 15:18:23 +03:00
|
|
|
import { createStore, compose } from 'redux';
|
|
|
|
import { insertScript, listenMessage } from '../../utils/inject';
|
|
|
|
import '../../../src/browser/extension/inject/pageScript';
|
|
|
|
|
|
|
|
function counter(state = 0, action) {
|
|
|
|
switch (action.type) {
|
|
|
|
case 'INCREMENT':
|
|
|
|
return state + 1;
|
|
|
|
case 'DECREMENT':
|
|
|
|
return state - 1;
|
|
|
|
default:
|
|
|
|
return state;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
describe('Redux enhancer', () => {
|
|
|
|
it('should create the store', async () => {
|
|
|
|
const message = await listenMessage(() => {
|
|
|
|
window.store = createStore(
|
|
|
|
counter,
|
|
|
|
window.__REDUX_DEVTOOLS_EXTENSION__()
|
|
|
|
);
|
2020-12-19 23:01:09 +03:00
|
|
|
expect(typeof window.store).toBe('object');
|
2020-10-26 15:18:23 +03:00
|
|
|
});
|
|
|
|
expect(message.type).toBe('INIT_INSTANCE');
|
|
|
|
expect(window.store.getState()).toBe(0);
|
|
|
|
insertScript('window.devToolsOptions = { serialize: false }');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should start monitoring', async () => {
|
|
|
|
let message = await listenMessage(() => {
|
|
|
|
window.postMessage({ type: 'START', source: '@devtools-extension' }, '*');
|
|
|
|
});
|
|
|
|
expect(message.type).toBe('START');
|
|
|
|
|
|
|
|
message = await listenMessage();
|
|
|
|
expect(message.type).toBe('STATE');
|
2020-12-19 23:01:09 +03:00
|
|
|
expect(message.actionsById).toMatch(
|
|
|
|
/{"0":{"type":"PERFORM_ACTION","action":{"type":"@@INIT"},"/
|
2020-10-26 15:18:23 +03:00
|
|
|
);
|
|
|
|
expect(message.computedStates).toBe('[{"state":0}]');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should perform actions', async () => {
|
|
|
|
let message = await listenMessage(() => {
|
|
|
|
window.store.dispatch({ type: 'INCREMENT' });
|
|
|
|
expect(window.store.getState()).toBe(1);
|
|
|
|
});
|
|
|
|
expect(message.type).toBe('ACTION');
|
2020-12-19 23:01:09 +03:00
|
|
|
expect(message.action).toMatch(
|
|
|
|
/{"type":"PERFORM_ACTION","action":{"type":"INCREMENT"},/
|
2020-10-26 15:18:23 +03:00
|
|
|
);
|
|
|
|
expect(message.payload).toBe('1');
|
|
|
|
|
|
|
|
message = await listenMessage(() => {
|
|
|
|
window.store.dispatch({ type: 'INCREMENT' });
|
|
|
|
expect(window.store.getState()).toBe(2);
|
|
|
|
});
|
|
|
|
expect(message.type).toBe('ACTION');
|
2020-12-19 23:01:09 +03:00
|
|
|
expect(message.action).toMatch(
|
|
|
|
/{"type":"PERFORM_ACTION","action":{"type":"INCREMENT"},/
|
2020-10-26 15:18:23 +03:00
|
|
|
);
|
|
|
|
expect(message.payload).toBe('2');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should dispatch actions remotely', async () => {
|
|
|
|
let message = await listenMessage(() => {
|
|
|
|
window.postMessage(
|
|
|
|
{
|
|
|
|
type: 'ACTION',
|
|
|
|
payload: "{ type: 'INCREMENT' }",
|
|
|
|
source: '@devtools-extension',
|
|
|
|
},
|
|
|
|
'*'
|
|
|
|
);
|
|
|
|
});
|
|
|
|
expect(message.type).toBe('ACTION');
|
|
|
|
|
|
|
|
message = await listenMessage();
|
|
|
|
expect(message.type).toBe('ACTION');
|
2020-12-19 23:01:09 +03:00
|
|
|
expect(message.action).toMatch(
|
|
|
|
/{"type":"PERFORM_ACTION","action":{"type":"INCREMENT"},/
|
2020-10-26 15:18:23 +03:00
|
|
|
);
|
|
|
|
expect(message.payload).toBe('3');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should cancel (toggle) action', async () => {
|
|
|
|
let message = await listenMessage(() => {
|
|
|
|
window.postMessage(
|
|
|
|
{
|
|
|
|
type: 'DISPATCH',
|
|
|
|
payload: { type: 'TOGGLE_ACTION', id: 1 },
|
|
|
|
source: '@devtools-extension',
|
|
|
|
},
|
|
|
|
'*'
|
|
|
|
);
|
|
|
|
});
|
|
|
|
expect(message.type).toBe('DISPATCH');
|
|
|
|
|
|
|
|
message = await listenMessage();
|
|
|
|
expect(message.type).toBe('STATE');
|
|
|
|
expect(window.store.getState()).toBe(2);
|
|
|
|
|
|
|
|
message = await listenMessage(() => {
|
|
|
|
window.postMessage(
|
|
|
|
{
|
|
|
|
type: 'DISPATCH',
|
|
|
|
payload: { type: 'TOGGLE_ACTION', id: 1 },
|
|
|
|
source: '@devtools-extension',
|
|
|
|
},
|
|
|
|
'*'
|
|
|
|
);
|
|
|
|
});
|
|
|
|
expect(message.type).toBe('DISPATCH');
|
|
|
|
|
|
|
|
message = await listenMessage();
|
|
|
|
expect(message.type).toBe('STATE');
|
|
|
|
expect(window.store.getState()).toBe(3);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should move back and forward (time travel)', async () => {
|
|
|
|
let message = await listenMessage(() => {
|
|
|
|
window.postMessage(
|
|
|
|
{
|
|
|
|
type: 'DISPATCH',
|
|
|
|
payload: { type: 'JUMP_TO_STATE', index: 2, actionId: 2 },
|
|
|
|
source: '@devtools-extension',
|
|
|
|
},
|
|
|
|
'*'
|
|
|
|
);
|
|
|
|
});
|
|
|
|
expect(message.type).toBe('DISPATCH');
|
|
|
|
expect(window.store.getState()).toBe(2);
|
|
|
|
|
|
|
|
message = await listenMessage(() => {
|
|
|
|
window.postMessage(
|
|
|
|
{
|
|
|
|
type: 'DISPATCH',
|
|
|
|
payload: { type: 'JUMP_TO_STATE', index: 3, actionId: 3 },
|
|
|
|
source: '@devtools-extension',
|
|
|
|
},
|
|
|
|
'*'
|
|
|
|
);
|
|
|
|
});
|
|
|
|
expect(message.type).toBe('DISPATCH');
|
|
|
|
expect(window.store.getState()).toBe(3);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should import state history', async () => {
|
|
|
|
let message = await listenMessage(() => {
|
|
|
|
window.postMessage(
|
|
|
|
{
|
|
|
|
type: 'IMPORT',
|
|
|
|
state: JSON.stringify({
|
|
|
|
monitorState: {},
|
|
|
|
actionsById: {
|
2021-06-18 06:56:36 +03:00
|
|
|
0: { type: 'PERFORM_ACTION', action: { type: '@@INIT' } },
|
|
|
|
1: { type: 'PERFORM_ACTION', action: { type: 'INCREMENT' } },
|
|
|
|
2: { type: 'PERFORM_ACTION', action: { type: 'INCREMENT' } },
|
2020-10-26 15:18:23 +03:00
|
|
|
},
|
|
|
|
nextActionId: 3,
|
|
|
|
stagedActionIds: [0, 1, 2],
|
|
|
|
skippedActionIds: [],
|
|
|
|
currentStateIndex: 2,
|
|
|
|
computedStates: [{ state: 0 }, { state: 1 }, { state: 2 }],
|
|
|
|
}),
|
|
|
|
source: '@devtools-extension',
|
|
|
|
},
|
|
|
|
'*'
|
|
|
|
);
|
|
|
|
});
|
|
|
|
expect(message.type).toBe('IMPORT');
|
|
|
|
message = await listenMessage();
|
|
|
|
expect(message.type).toBe('STATE');
|
|
|
|
expect(window.store.getState()).toBe(2);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should create the store with config parameters', async () => {
|
|
|
|
const message = await listenMessage(() => {
|
|
|
|
window.store = createStore(
|
|
|
|
counter,
|
|
|
|
window.__REDUX_DEVTOOLS_EXTENSION__({
|
2021-09-06 23:07:44 +03:00
|
|
|
actionsDenylist: ['SOME_ACTION'],
|
2020-10-26 15:18:23 +03:00
|
|
|
})
|
|
|
|
);
|
2020-12-19 23:01:09 +03:00
|
|
|
expect(typeof window.store).toBe('object');
|
2020-10-26 15:18:23 +03:00
|
|
|
});
|
|
|
|
expect(message.type).toBe('INIT_INSTANCE');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should create the store using old Redux api', async () => {
|
|
|
|
const message = await listenMessage(() => {
|
2021-06-18 06:56:36 +03:00
|
|
|
window.store =
|
|
|
|
window.__REDUX_DEVTOOLS_EXTENSION__()(createStore)(counter);
|
2020-12-19 23:01:09 +03:00
|
|
|
expect(typeof window.store).toBe('object');
|
2020-10-26 15:18:23 +03:00
|
|
|
});
|
|
|
|
expect(message.type).toBe('INIT_INSTANCE');
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should create the store with several enhancers', async () => {
|
|
|
|
const testEnhancer = (next) => (reducer, initialState, enhancer) =>
|
|
|
|
next(reducer, initialState, enhancer);
|
|
|
|
const message = await listenMessage(() => {
|
|
|
|
window.store = createStore(
|
|
|
|
counter,
|
|
|
|
compose(testEnhancer, window.__REDUX_DEVTOOLS_EXTENSION__())
|
|
|
|
);
|
2020-12-19 23:01:09 +03:00
|
|
|
expect(typeof window.store).toBe('object');
|
2020-10-26 15:18:23 +03:00
|
|
|
});
|
|
|
|
expect(message.type).toBe('INIT_INSTANCE');
|
|
|
|
});
|
|
|
|
});
|