Skip to content

Commit b6b2ff5

Browse files
committed
merge dev
2 parents cecc3e3 + 5700fce commit b6b2ff5

File tree

4 files changed

+175
-39
lines changed

4 files changed

+175
-39
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { mount , configure } from 'enzyme';
2+
3+
import React from 'react';
4+
import { MemoryRouter , NavLink } from 'react-router-dom';
5+
6+
import StateContainer from '../containers/StateContainer';
7+
import Chart from '../components/Chart';
8+
import Tree from '../components/Tree';
9+
10+
import Adapter from 'enzyme-adapter-react-16';
11+
12+
configure({ adapter: new Adapter() });
13+
14+
describe('testing react router path',()=>{
15+
const wrapper = mount(<MemoryRouter><StateContainer/></MemoryRouter>);
16+
it('NavLink has two paths', () => {
17+
expect(wrapper.find(NavLink)).toHaveLength(2);
18+
});
19+
it('First NavLink should be root', () => {
20+
expect(wrapper.find(NavLink).at(0).props().to).toBe('/');
21+
});
22+
it('Second NavLink should be chart', () => {
23+
expect(wrapper.find(NavLink).at(1).props().to).toBe('/chart');
24+
});
25+
});
26+
27+
describe('render test', () => {
28+
const wrapper = mount(
29+
<MemoryRouter>
30+
<StateContainer snapshot={ {data :'root'} }/>
31+
</MemoryRouter>);
32+
it('Clicking first NavLink should render Tree only', () => {
33+
wrapper.find(NavLink).at(0).simulate('click', { button: 0 });
34+
expect(wrapper.find(Tree)).toHaveLength(1);
35+
expect(wrapper.find(Chart)).toHaveLength(0);
36+
});
37+
it('Clicking second NavLink should render Chart only', () => {
38+
wrapper.find(NavLink).at(1).simulate('click', { button: 0 });
39+
expect(wrapper.find(Tree)).toHaveLength(0);
40+
expect(wrapper.find(Chart)).toHaveLength(1);
41+
});
42+
});

src/app/__tests__/dropdown.test.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import React from 'react';
2+
import { configure, shallow } from 'enzyme';
3+
import Adapter from 'enzyme-adapter-react-16';
4+
import Dropdown from '../components/Dropdown';
5+
6+
configure({ adapter: new Adapter() });
7+
8+
describe('unit testing for Dropdown.jsx', () => {
9+
let wrapper;
10+
const props = {
11+
options: [
12+
{ value: 2000, label: '0.5x' },
13+
{ value: 1000, label: '1.0x' },
14+
{ value: 500, label: '2.0x' },
15+
],
16+
handleChangeSpeed: jest.fn(),
17+
selectedOption: { value: 1000, label: '1.0x' }
18+
};
19+
beforeEach(() => {
20+
wrapper = shallow(<Dropdown {...props} />);
21+
});
22+
23+
describe('Component', () => {
24+
test('array of objects that have value and label should be options props', () => {
25+
expect(wrapper.props().options).toEqual(props.options);
26+
});
27+
test('selectedOption should be value property', () => {
28+
expect(wrapper.props().value).toEqual(props.selectedOption);
29+
})
30+
})
31+
32+
describe('handlechangeSpeed', () => {
33+
test('should invoke handleChangeSpeed onChange', () => {
34+
wrapper.simulate('change', { value: 2000, label: '0.5x' });
35+
expect(props.handleChangeSpeed).toHaveBeenCalled();
36+
});
37+
});
38+
});

src/app/styles/main.scss

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,6 @@
2020

2121
// slider component
2222
@import './components/rc-slider', './components/sliderHandle';
23+
24+
// d3 chart component
25+
@import './components/d3Tree';

src/extension/background.js

Lines changed: 92 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,79 @@
11
let bg;
2-
let snapshotArr = [];
3-
const mode = {
4-
persist: false,
5-
locked: false,
6-
paused: false,
7-
};
8-
let firstSnapshot = true;
2+
const tabsObj = {};
3+
function createTabObj() {
4+
return {
5+
snapshotArr: [],
6+
mode: {
7+
persist: false,
8+
locked: false,
9+
paused: false,
10+
},
11+
firstSnapshot: true,
12+
};
13+
}
914

1015
// establishing connection with devtools
1116
chrome.runtime.onConnect.addListener((port) => {
1217
bg = port;
1318

1419
// if snapshots were saved in the snapshotArr,
1520
// send it to devtools as soon as connection to devtools is made
16-
if (snapshotArr.length > 0) {
21+
if (Object.values(tabsObj)[0].snapshotArr.length > 0) {
22+
// later we want to send the entire tabsObj to devTools
23+
// but currently since devTools can only handle one tab at a time
24+
// we will test our obj assuming that the user opened only one tab
25+
// below is what we want the postMessage to look like eventually
26+
// ---------------------------------------------------------------
27+
// bg.postMessage({
28+
// action: 'initialConnectSnapshots',
29+
// payload: tabsObj,
30+
// });
31+
// ---------------------------------------------------------------
1732
bg.postMessage({
1833
action: 'initialConnectSnapshots',
1934
payload: {
20-
snapshots: snapshotArr,
21-
mode,
35+
snapshots: Object.values(tabsObj)[0].snapshotArr,
36+
mode: Object.values(tabsObj)[0].mode,
2237
},
2338
});
2439
}
2540

2641
// receive snapshot from devtools and send it to contentScript
2742
port.onMessage.addListener((msg) => {
28-
const { action, payload } = msg;
43+
// ---------------------------------------------------------------
44+
// message incoming from devTools should look like this:
45+
// {
46+
// action: 'emptySnap',
47+
// payload: tabsObj,
48+
// tabId: 101
49+
// }
50+
// ---------------------------------------------------------------
51+
const { action, payload, tabId } = msg;
2952
switch (action) {
3053
case 'import':
3154
snapshotArr = payload;
3255
break;
3356
case 'emptySnap':
34-
snapshotArr.splice(1);
57+
tabsObj[tabId].snapshotArr.splice(1);
3558
break;
3659
case 'setLock':
37-
mode.locked = payload;
60+
tabsObj[tabId].mode.locked = payload;
3861
break;
3962
case 'setPause':
40-
mode.paused = payload;
63+
tabsObj[tabId].mode.paused = payload;
4164
break;
4265
case 'setPersist':
43-
mode.persist = payload;
66+
tabsObj[tabId].mode.persist = payload;
4467
break;
4568
default:
4669
}
70+
71+
// Instead of sending the message to the active tab,
72+
// now we can send messages to specific tabs that we specify
73+
// using tabId
74+
// ---------------------------------------------------------------
75+
// chrome.tabs.sendMessage(tabId, msg);
76+
// ---------------------------------------------------------------
4777
// find active tab
4878
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
4979
// send message to tab
@@ -53,42 +83,65 @@ chrome.runtime.onConnect.addListener((port) => {
5383
});
5484

5585
// background.js recieves message from contentScript.js
56-
chrome.runtime.onMessage.addListener((request) => {
86+
chrome.runtime.onMessage.addListener((request, sender) => {
87+
// IGNORE THE AUTOMTAIC MESSAGE SENT BY CHROME WHEN CONTENT SCRIPT IS FIRST LOADED
88+
if (request.type === 'SIGN_CONNECT') return;
89+
90+
const tabId = sender.tab.id;
5791
const { action } = request;
58-
const { persist } = mode;
92+
let isReactTimeTravel = false;
93+
94+
// Filter out tabs that don't have react-time-travel
95+
if (action === 'tabReload' || action === 'recordSnap') {
96+
isReactTimeTravel = true;
97+
}
98+
99+
// everytime we get a new tabid, add it to the object
100+
if (isReactTimeTravel && !(tabId in tabsObj)) {
101+
tabsObj[tabId] = createTabObj();
102+
}
103+
104+
const { persist } = tabsObj[tabId].mode;
59105

60106
switch (action) {
61107
case 'tabReload':
62-
firstSnapshot = true;
63-
mode.locked = false;
64-
mode.paused = false;
65-
if (!persist) snapshotArr = [];
108+
tabsObj[tabId].firstSnapshot = true;
109+
tabsObj[tabId].mode.locked = false;
110+
tabsObj[tabId].mode.paused = false;
111+
if (!persist) tabsObj[tabId].snapshotArr = [];
66112
break;
67113
case 'recordSnap':
68-
if (firstSnapshot) {
69-
firstSnapshot = false;
114+
if (tabsObj[tabId].firstSnapshot) {
115+
tabsObj[tabId].firstSnapshot = false;
70116
// don't add anything to snapshot storage if mode is persisting for the initial snapshot
71-
if (!persist) snapshotArr.push(request.payload);
72-
bg.postMessage({
73-
action: 'initialConnectSnapshots',
74-
payload: {
75-
snapshots: snapshotArr,
76-
mode,
77-
},
78-
});
117+
if (!persist) tabsObj[tabId].snapshotArr.push(request.payload);
118+
if (bg) {
119+
bg.postMessage({
120+
action: 'initialConnectSnapshots',
121+
payload: {
122+
snapshots: tabsObj[tabId].snapshotArr,
123+
mode: tabsObj[tabId].mode,
124+
},
125+
});
126+
}
79127
break;
80128
}
81-
snapshotArr.push(request.payload);
82-
// TODO:
83-
// get active tab id
84-
// get snapshot arr from tab object
129+
130+
tabsObj[tabId].snapshotArr.push(request.payload);
85131

86132
// send message to devtools
87-
bg.postMessage({
88-
action: 'sendSnapshots',
89-
payload: snapshotArr,
90-
});
133+
if (bg) {
134+
bg.postMessage({
135+
action: 'sendSnapshots',
136+
payload: tabsObj[tabId].snapshotArr,
137+
});
138+
}
91139
break;
92140
default:
93141
}
94142
});
143+
144+
// when tab is closed, remove the tabid from the tabsObj
145+
chrome.tabs.onRemoved.addListener((tabId) => {
146+
delete tabsObj[tabId];
147+
});

0 commit comments

Comments
 (0)