Skip to content

Commit 9d65096

Browse files
committed
Merge branch 'jesse/ollie/merge' into jesse/enableAxTreeButtons
2 parents 575b060 + 5e34d93 commit 9d65096

File tree

5 files changed

+155
-63
lines changed

5 files changed

+155
-63
lines changed

src/app/components/StateRoute/Ax.tsx

Whitespace-only changes.

src/app/slices/mainSlice.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { createSlice } from '@reduxjs/toolkit';
22
import { InitialState } from '../FrontendTypes';
33
import _ from 'lodash';
4+
import Action from '../components/Actions/Action';
45

56
const initialState: InitialState = {
67
// we initialize what our initialState is here
@@ -550,4 +551,5 @@ export const {
550551
startReconnect,
551552
endConnect,
552553
toggleAxTree,
554+
toggleAxTree,
553555
} = mainSlice.actions;

src/backend/controllers/timeJump.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import componentActionsRecord from '../models/masterState';
22
import { Status } from '../types/backendTypes';
33
import Tree from '../models/tree';
4+
import { update } from 'lodash';
45

56
// THIS FILE CONTAINS NECCESSARY FUNCTIONALITY FOR TIME-TRAVEL FEATURE
67

@@ -48,6 +49,12 @@ async function updateReactFiberTree(
4849
targetSnapshot,
4950
circularComponentTable: Set<any> = new Set(),
5051
): Promise<void> {
52+
console.log(
53+
'updateReactFiberTree: targetSnapshot:',
54+
targetSnapshot,
55+
'circularComponentTable:',
56+
circularComponentTable,
57+
);
5158
if (!targetSnapshot) return;
5259
// Base Case: if has visited, return
5360
if (circularComponentTable.has(targetSnapshot)) {

src/backend/models/masterState.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export default {
1111
* @function clear - Clears componentActionsRecord
1212
*/
1313
clear: (): void => {
14+
// console.log(componentActionsRecord);
1415
componentActionsRecord = [];
1516
},
1617

src/extension/background.js

Lines changed: 145 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ const portsArr = [];
77
const reloaded = {};
88
const firstSnapshotReceived = {};
99

10+
// Toggle for recording accessibility snapshots
11+
let toggleAxRecord = false;
12+
1013
// There will be the same number of objects in here as there are
1114
// Reactime tabs open for each user application being worked on.
1215
let activeTab;
@@ -30,15 +33,14 @@ const pruneAxTree = (axTree) => {
3033
role
3134
} = node;
3235

33-
if(!name){
34-
if(ignored){
35-
name = {value: `ignored node: ${ignoredReasons[0].name}`};
36-
}
37-
else{
38-
name = {value: 'visible node with no name'};
36+
if (!name) {
37+
if (ignored) {
38+
name = { value: `ignored node: ${ignoredReasons[0].name}` };
39+
} else {
40+
name = { value: 'visible node with no name' };
3941
}
4042
}
41-
if(!name.value){
43+
if (!name.value) {
4244
name.value = 'visible node with no name';
4345
}
4446

@@ -61,6 +63,73 @@ const pruneAxTree = (axTree) => {
6163
return axArr;
6264
};
6365

66+
function attachDebugger(tabId, version) {
67+
return new Promise((resolve, reject) => {
68+
chrome.debugger.attach({ tabId: tabId }, version, () => {
69+
if (chrome.runtime.lastError) {
70+
reject(chrome.runtime.lastError);
71+
} else {
72+
resolve();
73+
}
74+
});
75+
});
76+
}
77+
78+
function sendDebuggerCommand(tabId, command, params = {}) {
79+
return new Promise((resolve, reject) => {
80+
chrome.debugger.sendCommand({ tabId: tabId }, command, params, (response) => {
81+
if (chrome.runtime.lastError) {
82+
reject(chrome.runtime.lastError);
83+
} else {
84+
resolve(response);
85+
}
86+
});
87+
});
88+
}
89+
90+
function detachDebugger(tabId) {
91+
return new Promise((resolve, reject) => {
92+
chrome.debugger.detach({ tabId: tabId }, () => {
93+
if (chrome.runtime.lastError) {
94+
reject(chrome.runtime.lastError);
95+
} else {
96+
resolve();
97+
}
98+
});
99+
});
100+
}
101+
102+
async function axRecord(tabId) {
103+
try {
104+
await attachDebugger(tabId, '1.3');
105+
await sendDebuggerCommand(tabId, 'Accessibility.enable');
106+
const response = await sendDebuggerCommand(tabId, 'Accessibility.getFullAXTree');
107+
const pruned = pruneAxTree(response.nodes);
108+
await detachDebugger(tabId);
109+
return pruned;
110+
} catch (error) {
111+
console.error('axRecord debugger command failed:', error);
112+
}
113+
}
114+
115+
async function replaceEmptySnap(tabsObj, tabId, toggleAxRecord) {
116+
console.log(
117+
'background.js: top of replaceEmptySnap: tabsObj[tabId]:',
118+
JSON.parse(JSON.stringify(tabsObj[tabId])),
119+
);
120+
if (tabsObj[tabId].currLocation.axSnapshot === 'emptyAxSnap' && toggleAxRecord === true) {
121+
// add new ax snapshot to currlocation
122+
const addedAxSnap = await axRecord(tabId);
123+
tabsObj[tabId].currLocation.axSnapshot = addedAxSnap;
124+
// modify array to include the new recorded ax snapshot
125+
tabsObj[tabId].axSnapshots[tabsObj[tabId].currLocation.index] = addedAxSnap;
126+
}
127+
console.log(
128+
'background.js: bottom of replaceEmptySnap: tabsObj[tabId]:',
129+
JSON.parse(JSON.stringify(tabsObj[tabId])),
130+
);
131+
}
132+
64133
// This function will create the first instance of the test app's tabs object
65134
// which will hold test app's snapshots, link fiber tree info, chrome tab info, etc.
66135
function createTabObj(title) {
@@ -248,7 +317,7 @@ chrome.runtime.onConnect.addListener((port) => {
248317
// INCOMING MESSAGE FROM FRONTEND (MainContainer) TO BACKGROUND.js
249318
// listen for message containing a snapshot from devtools and send it to contentScript -
250319
// (i.e. they're all related to the button actions on Reactime)
251-
port.onMessage.addListener((msg) => {
320+
port.onMessage.addListener(async (msg) => {
252321
// msg is action denoting a time jump in devtools
253322
// ---------------------------------------------------------------
254323
// message incoming from devTools should look like this:
@@ -322,6 +391,25 @@ chrome.runtime.onConnect.addListener((port) => {
322391
chrome.tabs.sendMessage(tabId, msg);
323392
return true;
324393

394+
case 'toggleAxRecord':
395+
toggleAxRecord = !toggleAxRecord;
396+
397+
await replaceEmptySnap(tabsObj, tabId, toggleAxRecord);
398+
399+
// sends new tabs obj to devtools
400+
if (portsArr.length > 0) {
401+
portsArr.forEach((bg) =>
402+
bg.postMessage({
403+
action: 'sendSnapshots',
404+
payload: tabsObj,
405+
tabId,
406+
}),
407+
);
408+
} else {
409+
console.log('background.js: portsArr.length < 0');
410+
}
411+
return true; // return true so that port remains open
412+
325413
case 'reinitialize':
326414
chrome.tabs.sendMessage(tabId, msg);
327415
return true;
@@ -372,7 +460,34 @@ chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) => {
372460
break;
373461
}
374462
case 'jumpToSnap': {
463+
console.log(
464+
'background.js: top of jumpToSnap: tabsObj[tabId]:',
465+
JSON.parse(JSON.stringify(tabsObj[tabId])),
466+
);
375467
changeCurrLocation(tabsObj[tabId], tabsObj[tabId].hierarchy, index, name);
468+
// hack to test without message from mainSlice
469+
// toggleAxRecord = true;
470+
// record ax tree snapshot of the state that has now been jumped to if user did not toggle button on
471+
await replaceEmptySnap(tabsObj, tabId, toggleAxRecord);
472+
473+
console.log(
474+
'background.js: bottom of jumpToSnap: tabsObj[tabId]:',
475+
JSON.parse(JSON.stringify(tabsObj[tabId])),
476+
);
477+
478+
// sends new tabs obj to devtools
479+
if (portsArr.length > 0) {
480+
portsArr.forEach((bg) =>
481+
bg.postMessage({
482+
action: 'sendSnapshots',
483+
payload: tabsObj,
484+
tabId,
485+
}),
486+
);
487+
} else {
488+
console.log('background.js: portsArr.length < 0');
489+
}
490+
376491
if (portsArr.length > 0) {
377492
portsArr.forEach((bg) =>
378493
bg.postMessage({
@@ -383,6 +498,7 @@ chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) => {
383498
}
384499
break;
385500
}
501+
386502
// Confirmed React Dev Tools installed, send this info to frontend
387503
case 'devToolsInstalled': {
388504
tabsObj[tabId].status.reactDevToolsInstalled = true;
@@ -431,61 +547,9 @@ chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) => {
431547
'background.js: top of recordSnap: tabsObj[tabId]:',
432548
JSON.parse(JSON.stringify(tabsObj[tabId])),
433549
);
434-
function addAxSnap(snap) {
435-
const pruned = pruneAxTree(snap);
436-
tabsObj[tabId].axSnapshots.push(pruned);
437-
return pruned;
438-
}
439-
440-
function attachDebugger(tabId, version) {
441-
return new Promise((resolve, reject) => {
442-
chrome.debugger.attach({ tabId: tabId }, version, () => {
443-
if (chrome.runtime.lastError) {
444-
reject(chrome.runtime.lastError);
445-
} else {
446-
resolve();
447-
}
448-
});
449-
});
450-
}
451-
452-
function sendDebuggerCommand(tabId, command, params = {}) {
453-
return new Promise((resolve, reject) => {
454-
chrome.debugger.sendCommand({ tabId: tabId }, command, params, (response) => {
455-
if (chrome.runtime.lastError) {
456-
reject(chrome.runtime.lastError);
457-
} else {
458-
resolve(response);
459-
}
460-
});
461-
});
462-
}
463550

464-
function detachDebugger(tabId) {
465-
return new Promise((resolve, reject) => {
466-
chrome.debugger.detach({ tabId: tabId }, () => {
467-
if (chrome.runtime.lastError) {
468-
reject(chrome.runtime.lastError);
469-
} else {
470-
resolve();
471-
}
472-
});
473-
});
474-
}
551+
console.log('background.js: recordSnap case: toggleAxRecord:', toggleAxRecord);
475552

476-
async function axRecord(tabId) {
477-
try {
478-
await attachDebugger(tabId, '1.3');
479-
await sendDebuggerCommand(tabId, 'Accessibility.enable');
480-
const response = await sendDebuggerCommand(tabId, 'Accessibility.getFullAXTree');
481-
console.log('response: ', response);
482-
const addedAxSnap = addAxSnap(response.nodes);
483-
await detachDebugger(tabId);
484-
return addedAxSnap;
485-
} catch (error) {
486-
console.error('axRecord debugger command failed:', error);
487-
}
488-
}
489553
const sourceTab = tabId;
490554
tabsObj[tabId].webMetrics = metrics;
491555

@@ -494,7 +558,16 @@ chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) => {
494558
reloaded[tabId] = false;
495559
tabsObj[tabId].webMetrics = metrics;
496560
tabsObj[tabId].snapshots.push(request.payload);
497-
const addedAxSnap = await axRecord(tabId);
561+
562+
// check if accessibility recording has been toggled on
563+
let addedAxSnap;
564+
if (toggleAxRecord === true) {
565+
addedAxSnap = await axRecord(tabId);
566+
tabsObj[tabId].axSnapshots.push(addedAxSnap);
567+
} else {
568+
addedAxSnap = 'emptyAxSnap';
569+
tabsObj[tabId].axSnapshots.push(addedAxSnap);
570+
}
498571
sendToHierarchy(
499572
tabsObj[tabId],
500573
new HistoryNode(tabsObj[tabId], request.payload, addedAxSnap),
@@ -535,7 +608,16 @@ chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) => {
535608
tabsObj[tabId].snapshots.push(request.payload);
536609
// INVOKING buildHierarchy FIGURE OUT WHAT TO PASS IN
537610
if (!tabsObj[tabId][index]) {
538-
const addedAxSnap = await axRecord(tabId);
611+
// check if accessibility recording has been toggled on
612+
let addedAxSnap;
613+
if (toggleAxRecord === true) {
614+
addedAxSnap = await axRecord(tabId);
615+
tabsObj[tabId].axSnapshots.push(addedAxSnap);
616+
} else {
617+
addedAxSnap = 'emptyAxSnap';
618+
tabsObj[tabId].axSnapshots.push(addedAxSnap);
619+
}
620+
539621
sendToHierarchy(
540622
tabsObj[tabId],
541623
new HistoryNode(tabsObj[tabId], request.payload, addedAxSnap),

0 commit comments

Comments
 (0)