Skip to content

Commit 2045949

Browse files
Update SceneGraph Inspector to use new method for building tree and other improvements (#661)
Co-authored-by: Bronley Plumb <[email protected]>
1 parent 36ad559 commit 2045949

18 files changed

+1088
-869
lines changed

.github/workflows/create-vsix-from-pr.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
run: echo "TOKEN=${{ steps.generate-token.outputs.token }}" >> $GITHUB_ENV
1818
#trigger the build on vscode-brightscript-language
1919
- name: Build vsix for branch "${{ github.head_ref}}"
20-
uses: aurelien-baudet/workflow-dispatch@v2.1.1
20+
uses: the-actions-org/workflow-dispatch@v4
2121
id: create-vsix
2222
with:
2323
workflow: create-vsix

package-lock.json

Lines changed: 210 additions & 200 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@
8282
"resolve": "^1.22.8",
8383
"roku-debug": "^0.22.0",
8484
"roku-deploy": "^3.12.6",
85-
"roku-test-automation": "^2.0.10",
85+
"roku-test-automation": "^2.2.1",
8686
"semver": "^7.1.3",
8787
"source-map": "^0.7.3",
8888
"strip-ansi": "^5.2.0",
@@ -321,17 +321,17 @@
321321
},
322322
{
323323
"command": "extension.brightscript.rokuDeviceView.refreshScreenshot",
324-
"when": "view == rokuDeviceView && !brightscript.rokuDeviceView.enableScreenshotCapture",
324+
"when": "view == rokuDeviceView && !brightscript.rokuDeviceView.enableScreenshotCaptureAutoRefresh",
325325
"group": "navigation@1"
326326
},
327327
{
328328
"command": "extension.brightscript.rokuDeviceView.resumeScreenshotCapture",
329-
"when": "view == rokuDeviceView && !brightscript.rokuDeviceView.enableScreenshotCapture && !brightscript.rokuDeviceView.isInspectingNodes",
329+
"when": "view == rokuDeviceView && !brightscript.rokuDeviceView.enableScreenshotCaptureAutoRefresh && !brightscript.rokuDeviceView.isInspectingNodes",
330330
"group": "navigation@2"
331331
},
332332
{
333333
"command": "extension.brightscript.rokuDeviceView.pauseScreenshotCapture",
334-
"when": "view == rokuDeviceView && brightscript.rokuDeviceView.enableScreenshotCapture && !brightscript.rokuDeviceView.isInspectingNodes",
334+
"when": "view == rokuDeviceView && brightscript.rokuDeviceView.enableScreenshotCaptureAutoRefresh",
335335
"group": "navigation@2"
336336
},
337337
{
@@ -351,7 +351,7 @@
351351
},
352352
{
353353
"command": "extension.brightscript.disconnectFromDevice",
354-
"when": "view == rokuDeviceView && brightscript.rokuDeviceView.isOnDeviceComponentAvailable",
354+
"when": "view == rokuDeviceView && brightscript.isOnDeviceComponentAvailable",
355355
"group": "navigation@5"
356356
},
357357
{

src/managers/RtaManager.ts

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export class RtaManager {
2424
public device?: rta.RokuDevice;
2525

2626
private webviewViewProviderManager?: WebviewViewProviderManager;
27-
private lastStoreNodesResponse: Awaited<ReturnType<typeof rta.odc.storeNodeReferences>>;
27+
private lastAppUIResponse: rta.AppUIResponse | undefined;
2828

2929
public setupRtaWithConfig(config: { host: string; password: string; logLevel?: string; disableScreenSaver?: boolean; injectRdbOnDeviceComponent?: boolean }) {
3030
const enableDebugging = ['info', 'debug', 'trace'].includes(config.logLevel);
@@ -67,20 +67,7 @@ export class RtaManager {
6767
public async sendOdcRequest(requestorId: string, command: string, context: { args: any; options: any }) {
6868
const { args, options } = context;
6969

70-
if (command === rta.RequestType.storeNodeReferences) {
71-
this.lastStoreNodesResponse = await rta.odc.storeNodeReferences(args, options);
72-
73-
const viewIds = [];
74-
if (requestorId === ViewProviderId.rokuDeviceView) {
75-
viewIds.push(ViewProviderId.sceneGraphInspectorView);
76-
} else if (requestorId === ViewProviderId.sceneGraphInspectorView) {
77-
viewIds.push(ViewProviderId.rokuDeviceView);
78-
}
79-
this.webviewViewProviderManager.sendMessageToWebviews(viewIds, {
80-
event: ViewProviderEvent.onStoredNodeReferencesUpdated
81-
});
82-
return this.lastStoreNodesResponse;
83-
} else if (command === rta.RequestType.writeFile) {
70+
if (command === rta.RequestType.writeFile) {
8471
// We can't access files from the webview so we just store the path and access it in node instead
8572
const directoryPath = path.dirname(args.destinationPath);
8673
// We always try to make the directory. Doesn't fail if it already exists
@@ -93,16 +80,35 @@ export class RtaManager {
9380
path: args.destinationPath
9481
}, options);
9582
} else {
96-
return this.onDeviceComponent[command](args, options);
83+
const result = await this.onDeviceComponent[command](args, options);
84+
return result;
9785
}
9886
}
9987

100-
public setWebviewViewProviderManager(manager: WebviewViewProviderManager) {
101-
this.webviewViewProviderManager = manager;
88+
public async getAppUI(requestorId: string) {
89+
await this.sendOdcRequest(requestorId, 'assignElementIdOnAllNodes', { args: {}, options: {} });
90+
this.lastAppUIResponse = await rta.ecp.getAppUI();
91+
92+
const viewIds = [];
93+
if (requestorId === ViewProviderId.rokuDeviceView) {
94+
viewIds.push(ViewProviderId.sceneGraphInspectorView);
95+
} else if (requestorId === ViewProviderId.sceneGraphInspectorView) {
96+
viewIds.push(ViewProviderId.rokuDeviceView);
97+
}
98+
99+
// We want to notify the other view providers that the app UI has been updated. Not sending actual payload to avoid overhead if they aren't interested in it
100+
this.webviewViewProviderManager.sendMessageToWebviews(viewIds, {
101+
event: ViewProviderEvent.onStoredAppUIUpdated
102+
});
103+
return this.lastAppUIResponse;
104+
}
105+
106+
public getStoredAppUI() {
107+
return this.lastAppUIResponse;
102108
}
103109

104-
public getStoredNodeReferences() {
105-
return this.lastStoreNodesResponse;
110+
public setWebviewViewProviderManager(manager: WebviewViewProviderManager) {
111+
this.webviewViewProviderManager = manager;
106112
}
107113

108114
private updateDeviceAvailabilityOnWebViewProviders() {

src/managers/WebviewViewProviderManager.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ export class WebviewViewProviderManager {
8989

9090
// Mainly for communicating between webviews
9191
public sendMessageToWebviews(viewIds: string | string[], message) {
92+
// console.log(`WebviewViewProviderManager: sendMessageToWebviews: ${viewIds} ${JSON.stringify(message)}`);
9293
if (typeof viewIds === 'string') {
9394
viewIds = [viewIds];
9495
}

src/viewProviders/BaseRdbViewProvider.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,27 @@ export abstract class BaseRdbViewProvider extends BaseWebviewViewProvider {
4848
return Promise.resolve(true);
4949
});
5050

51-
this.addMessageCommandCallback(ViewProviderCommand.getStoredNodeReferences, (message) => {
52-
const response = this.dependencies.rtaManager.getStoredNodeReferences();
51+
this.addMessageCommandCallback(ViewProviderCommand.getStoredAppUI, (message) => {
52+
const response = this.dependencies.rtaManager.getStoredAppUI();
5353
this.postOrQueueMessage(this.createResponseMessage(message, response));
5454
return Promise.resolve(true);
5555
});
56+
57+
this.addMessageCommandCallback(ViewProviderCommand.getAppUI, async (message) => {
58+
try {
59+
const appUIResponse = await this.dependencies.rtaManager.getAppUI(this.id);
60+
61+
this.postOrQueueMessage(this.createResponseMessage(message, {
62+
success: true,
63+
response: appUIResponse
64+
}));
65+
} catch (e) {
66+
this.postOrQueueMessage(this.createResponseMessage(message, {
67+
success: false
68+
}));
69+
}
70+
return true;
71+
});
5672
}
5773

5874
protected onViewReady() {

src/viewProviders/BaseWebviewViewProvider.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,12 @@ export abstract class BaseWebviewViewProvider implements vscode.WebviewViewProvi
126126
} else if (command === ViewProviderCommand.setVscodeContext) {
127127
const context = message.context;
128128
await vscodeContextManager.set(context.key, context.value);
129+
} else if (command === ViewProviderCommand.getVscodeContext) {
130+
const context = message.context;
131+
const value = vscodeContextManager.get(context.key);
132+
this.postOrQueueMessage(this.createResponseMessage(message, {
133+
value: value
134+
}));
129135
} else if (command === ViewProviderCommand.sendMessageToWebviews) {
130136
const context = message.context;
131137
this.webviewViewProviderManager.sendMessageToWebviews(context.viewIds, context.message);

src/viewProviders/ViewProviderCommand.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
export enum ViewProviderCommand {
22
deleteRokuFile = 'deleteRokuFile',
3+
getAppUI = 'getAppUI',
4+
getStoredAppUI = 'getStoredAppUI',
35
getScreenshot = 'getScreenshot',
4-
getStoredNodeReferences = 'getStoredNodeReferences',
56
getStoredRokuAppOverlays = 'getStoredRokuAppOverlays',
7+
getVscodeContext = 'getVscodeContext',
68
getWorkspaceState = 'getWorkspaceState',
7-
openRokuFile = 'openRokuFile',
89
loadRokuAppOverlaysThumbnails = 'loadRokuAppOverlaysThumbnails',
10+
openRokuFile = 'openRokuFile',
911
runRokuAutomationConfig = 'runRokuAutomationConfig',
1012
sendMessageToWebviews = 'sendMessageToWebviews',
1113
sendReplRequest = 'sendReplRequest',
Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
export enum ViewProviderEvent {
2-
onTreeNodeFocused = 'onTreeNodeFocused',
2+
onNodeFocused = 'onNodeFocused',
33
onDeviceAvailabilityChange = 'onDeviceAvailabilityChange',
44
onVscodeCommandReceived = 'onVscodeCommandReceived',
55
onRegistryUpdated = 'onRegistryUpdated',
6-
onStoredNodeReferencesUpdated = 'onStoredNodeReferencesUpdated',
6+
onStoredAppUIUpdated = 'onStoredAppUIUpdated',
77
onRokuAutomationConfigsLoaded = 'onRokuAutomationConfigsLoaded',
88
onRokuAutomationImportAllAutomations = 'onRokuAutomationImportAllAutomations',
99
onRokuAutomationExportAllAutomations = 'onRokuAutomationExportAllAutomations',
1010
onRokuAutomationConfigStepChange = 'onRokuAutomationConfigStepChange',
1111
onRokuAutomationKeyPressed = 'onRokuAutomationKeyPressed',
1212
onRokuAppOverlayAdded = 'onRokuAppOverlayAdded',
13-
onRokuAppOverlayThumbnailsLoaded = 'onRokuAppOverlayThumbnailsLoaded'
13+
onRokuAppOverlayThumbnailsLoaded = 'onRokuAppOverlayThumbnailsLoaded',
14+
onVscodeContextSet = 'onVscodeContextSet'
1415
}

webviews/src/ExtensionIntermediary.ts

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
import type * as rta from 'roku-test-automation';
33
import { RequestType } from 'roku-test-automation/client/dist/types/OnDeviceComponent';
44
import type { VscodeCommand } from '../../src/commands/VscodeCommand';
5-
import type { ViewProviderEvent } from '../../src/viewProviders/ViewProviderEvent';
5+
import { ViewProviderEvent } from '../../src/viewProviders/ViewProviderEvent';
66
import { ViewProviderCommand } from '../../src/viewProviders/ViewProviderCommand';
7-
import type { DeleteEntireRegistrySectionsArgs, DeleteNodeReferencesArgs, DeleteRegistrySectionsArgs, FindNodesAtLocationArgs, GetFocusedNodeArgs, GetNodesInfoArgs, GetNodesWithPropertiesArgs, GetValueArgs, GetValuesArgs, HasFocusArgs, IsInFocusChainArgs, OnFieldChangeOnceArgs, ReadRegistryArgs, RequestOptions, SetValueArgs, StoreNodeReferencesArgs, WriteRegistryArgs, GetVolumeListArgs, GetDirectoryListingArgs, StatPathArgs, RenameFileArgs, DeleteFileArgs, CreateDirectoryArgs, RemoveNodeArgs, RemoveNodeChildrenArgs, FocusNodeArgs } from 'roku-test-automation';
7+
import type { DeleteEntireRegistrySectionsArgs, DeleteRegistrySectionsArgs, FindNodesAtLocationArgs, GetFocusedNodeArgs, GetNodesInfoArgs, GetNodesWithPropertiesArgs, GetValueArgs, GetValuesArgs, HasFocusArgs, IsInFocusChainArgs, OnFieldChangeOnceArgs, ReadRegistryArgs, RequestOptions, SetValueArgs, WriteRegistryArgs, GetVolumeListArgs, GetDirectoryListingArgs, StatPathArgs, RenameFileArgs, DeleteFileArgs, CreateDirectoryArgs, RemoveNodeArgs, RemoveNodeChildrenArgs, FocusNodeArgs, AppUIResponse, ConvertKeyPathToSceneKeyPathArgs } from 'roku-test-automation';
88

99
class ExtensionIntermediary {
1010
private inflightRequests = {};
@@ -90,11 +90,23 @@ class ExtensionIntermediary {
9090
});
9191
}
9292

93-
public setVscodeContext(key: string, value: boolean | number | string) {
93+
public setVscodeContext(key: string, value: boolean | number | string, notifyViewIds: string | string[] = []) {
9494
this.postMessage(this.createCommandMessage(ViewProviderCommand.setVscodeContext, {
9595
key: key,
9696
value: value
9797
}));
98+
99+
const message = intermediary.createEventMessage(ViewProviderEvent.onVscodeContextSet, {
100+
key: key,
101+
value: value
102+
});
103+
intermediary.sendMessageToWebviews(notifyViewIds, message);
104+
}
105+
106+
public getVscodeContext(key: string) {
107+
return this.sendCommand(ViewProviderCommand.getVscodeContext, {
108+
key: key
109+
});
98110
}
99111

100112
public updateWorkspaceState(key: string, value: any) {
@@ -111,8 +123,13 @@ class ExtensionIntermediary {
111123
});
112124
}
113125

114-
public async getStoredNodeReferences() {
115-
return this.sendCommand<ReturnType<typeof rta.odc.storeNodeReferences>>(ViewProviderCommand.getStoredNodeReferences);
126+
public async getStoredAppUI() {
127+
return this.sendCommand<AppUIResponse | undefined>(ViewProviderCommand.getStoredAppUI);
128+
}
129+
130+
public async getAppUI() {
131+
const { response } = await this.sendCommand(ViewProviderCommand.getAppUI);
132+
return response as AppUIResponse;
116133
}
117134

118135
public observeEvent(eventName: string, callback: ObserverCallback) {
@@ -126,6 +143,10 @@ class ExtensionIntermediary {
126143
}
127144

128145
public sendMessageToWebviews(viewIds: string | string[], message) {
146+
if (!viewIds || (Array.isArray(viewIds) && viewIds.length === 0)) {
147+
return;
148+
}
149+
129150
this.postMessage(this.createCommandMessage(ViewProviderCommand.sendMessageToWebviews, {
130151
viewIds: viewIds,
131152
message: message
@@ -201,14 +222,6 @@ class ODCIntermediary {
201222
return this.sendOdcMessage<ReturnType<typeof rta.odc.deleteEntireRegistry>>(RequestType.deleteEntireRegistry, args, options);
202223
}
203224

204-
public async storeNodeReferences(args?: StoreNodeReferencesArgs, options?: RequestOptions) {
205-
return this.sendOdcMessage<ReturnType<typeof rta.odc.storeNodeReferences>>(RequestType.storeNodeReferences, args, options);
206-
}
207-
208-
public async deleteNodeReferences(args: DeleteNodeReferencesArgs, options?: RequestOptions) {
209-
return this.sendOdcMessage<ReturnType<typeof rta.odc.deleteNodeReferences>>(RequestType.deleteNodeReferences, args, options);
210-
}
211-
212225
public async getNodesWithProperties(args: GetNodesWithPropertiesArgs, options?: RequestOptions) {
213226
return this.sendOdcMessage<ReturnType<typeof rta.odc.getNodesWithProperties>>(RequestType.getNodesWithProperties, args, options);
214227
}
@@ -256,6 +269,10 @@ class ODCIntermediary {
256269
public async focusNode(args: FocusNodeArgs, options?: RequestOptions) {
257270
return this.sendOdcMessage<ReturnType<typeof rta.odc.focusNode>>(RequestType.focusNode, args, options);
258271
}
272+
273+
public async convertKeyPathToSceneKeyPath(args: ConvertKeyPathToSceneKeyPathArgs, options?: RequestOptions) {
274+
return this.sendOdcMessage<ReturnType<typeof rta.odc.convertKeyPathToSceneKeyPath>>(RequestType.convertKeyPathToSceneKeyPath, args, options);
275+
}
259276
}
260277

261278
type ObserverCallback = (message) => void;

0 commit comments

Comments
 (0)