chore: use ContextManager for trace-viewer state handling
This commit is contained in:
parent
6491e5b415
commit
33e4b31dcc
|
|
@ -25,13 +25,13 @@ import type { TreeState } from '@web/components/treeView';
|
|||
import { TreeView } from '@web/components/treeView';
|
||||
import type { ActionTraceEventInContext, ActionTreeItem } from './modelUtil';
|
||||
import type { Boundaries } from '../geometry';
|
||||
import { WorkbenchContext } from './workbenchContext';
|
||||
|
||||
export interface ActionListProps {
|
||||
actions: ActionTraceEventInContext[],
|
||||
selectedAction: ActionTraceEventInContext | undefined,
|
||||
selectedTime: Boundaries | undefined,
|
||||
setSelectedTime: (time: Boundaries | undefined) => void,
|
||||
sdkLanguage: Language | undefined;
|
||||
onSelected: (action: ActionTraceEventInContext) => void,
|
||||
onHighlighted: (action: ActionTraceEventInContext | undefined) => void,
|
||||
revealConsole: () => void,
|
||||
|
|
@ -45,12 +45,12 @@ export const ActionList: React.FC<ActionListProps> = ({
|
|||
selectedAction,
|
||||
selectedTime,
|
||||
setSelectedTime,
|
||||
sdkLanguage,
|
||||
onSelected,
|
||||
onHighlighted,
|
||||
revealConsole,
|
||||
isLive,
|
||||
}) => {
|
||||
const { sdkLanguage } = React.useContext(WorkbenchContext);
|
||||
const [treeState, setTreeState] = React.useState<TreeState>({ expandedItems: new Map() });
|
||||
const { rootItem, itemMap } = React.useMemo(() => modelUtil.buildActionTree(actions), [actions]);
|
||||
|
||||
|
|
|
|||
|
|
@ -24,11 +24,12 @@ import { asLocator } from '@isomorphic/locatorGenerators';
|
|||
import type { Language } from '@isomorphic/locatorGenerators';
|
||||
import { PlaceholderPanel } from './placeholderPanel';
|
||||
import type { ActionTraceEventInContext } from './modelUtil';
|
||||
import { WorkbenchContext } from './workbenchContext';
|
||||
|
||||
export const CallTab: React.FunctionComponent<{
|
||||
action: ActionTraceEventInContext | undefined,
|
||||
sdkLanguage: Language | undefined,
|
||||
}> = ({ action, sdkLanguage }) => {
|
||||
}> = ({ action }) => {
|
||||
const { sdkLanguage } = React.useContext(WorkbenchContext);
|
||||
if (!action)
|
||||
return <PlaceholderPanel text='No action selected' />;
|
||||
const params = { ...action.params };
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ import * as React from 'react';
|
|||
import type * as modelUtil from './modelUtil';
|
||||
import { PlaceholderPanel } from './placeholderPanel';
|
||||
import { renderAction } from './actionList';
|
||||
import type { Language } from '@isomorphic/locatorGenerators';
|
||||
import type { StackFrame } from '@protocol/channels';
|
||||
import { WorkbenchContext } from './workbenchContext';
|
||||
|
||||
type ErrorDescription = {
|
||||
action?: modelUtil.ActionTraceEventInContext;
|
||||
|
|
@ -44,9 +44,9 @@ export function useErrorsTabModel(model: modelUtil.MultiTraceModel | undefined):
|
|||
|
||||
export const ErrorsTab: React.FunctionComponent<{
|
||||
errorsModel: ErrorsTabModel,
|
||||
sdkLanguage: Language,
|
||||
revealInSource: (error: ErrorDescription) => void,
|
||||
}> = ({ errorsModel, sdkLanguage, revealInSource }) => {
|
||||
}> = ({ errorsModel, revealInSource }) => {
|
||||
const { sdkLanguage } = React.useContext(WorkbenchContext);
|
||||
if (!errorsModel.errors.size)
|
||||
return <PlaceholderPanel text='No errors' />;
|
||||
|
||||
|
|
|
|||
|
|
@ -15,18 +15,18 @@
|
|||
*/
|
||||
|
||||
import { CodeMirrorWrapper } from '@web/components/codeMirrorWrapper';
|
||||
import type { Language } from '@web/components/codeMirrorWrapper';
|
||||
import { ToolbarButton } from '@web/components/toolbarButton';
|
||||
import { copy } from '@web/uiUtils';
|
||||
import * as React from 'react';
|
||||
import './sourceTab.css';
|
||||
import { WorkbenchContext } from './workbenchContext';
|
||||
|
||||
export const InspectorTab: React.FunctionComponent<{
|
||||
sdkLanguage: Language,
|
||||
setIsInspecting: (isInspecting: boolean) => void,
|
||||
highlightedLocator: string,
|
||||
setHighlightedLocator: (locator: string) => void,
|
||||
}> = ({ sdkLanguage, setIsInspecting, highlightedLocator, setHighlightedLocator }) => {
|
||||
}> = ({ setIsInspecting, highlightedLocator, setHighlightedLocator }) => {
|
||||
const { sdkLanguage } = React.useContext(WorkbenchContext);
|
||||
return <div className='vbox' style={{ backgroundColor: 'var(--vscode-sideBar-background)' }}>
|
||||
<div style={{ margin: '10px 0px 10px 10px', color: 'var(--vscode-editorCodeLens-foreground)', flex: 'none' }}>Locator</div>
|
||||
<div style={{ margin: '0 10px 10px', flex: 'auto' }}>
|
||||
|
|
|
|||
|
|
@ -29,17 +29,18 @@ import type { Language } from '@isomorphic/locatorGenerators';
|
|||
import { locatorOrSelectorAsSelector } from '@isomorphic/locatorParser';
|
||||
import { TabbedPaneTab } from '@web/components/tabbedPane';
|
||||
import { BrowserFrame } from './browserFrame';
|
||||
import { WorkbenchContext } from './workbenchContext';
|
||||
|
||||
export const SnapshotTab: React.FunctionComponent<{
|
||||
action: ActionTraceEvent | undefined,
|
||||
sdkLanguage: Language,
|
||||
testIdAttributeName: string,
|
||||
isInspecting: boolean,
|
||||
setIsInspecting: (isInspecting: boolean) => void,
|
||||
highlightedLocator: string,
|
||||
setHighlightedLocator: (locator: string) => void,
|
||||
openPage?: (url: string, target?: string) => Window | any,
|
||||
}> = ({ action, sdkLanguage, testIdAttributeName, isInspecting, setIsInspecting, highlightedLocator, setHighlightedLocator, openPage }) => {
|
||||
}> = ({ action, testIdAttributeName, isInspecting, setIsInspecting, highlightedLocator, setHighlightedLocator, openPage }) => {
|
||||
const { sdkLanguage } = React.useContext(WorkbenchContext);
|
||||
const [measure, ref] = useMeasure<HTMLDivElement>();
|
||||
const [snapshotTab, setSnapshotTab] = React.useState<'action'|'before'|'after'>('action');
|
||||
|
||||
|
|
@ -166,7 +167,6 @@ export const SnapshotTab: React.FunctionComponent<{
|
|||
>
|
||||
<InspectModeController
|
||||
isInspecting={isInspecting}
|
||||
sdkLanguage={sdkLanguage}
|
||||
testIdAttributeName={testIdAttributeName}
|
||||
highlightedLocator={highlightedLocator}
|
||||
setHighlightedLocator={setHighlightedLocator}
|
||||
|
|
@ -174,7 +174,6 @@ export const SnapshotTab: React.FunctionComponent<{
|
|||
iteration={loadingRef.current.iteration} />
|
||||
<InspectModeController
|
||||
isInspecting={isInspecting}
|
||||
sdkLanguage={sdkLanguage}
|
||||
testIdAttributeName={testIdAttributeName}
|
||||
highlightedLocator={highlightedLocator}
|
||||
setHighlightedLocator={setHighlightedLocator}
|
||||
|
|
@ -229,12 +228,12 @@ function renderTitle(snapshotTitle: string): string {
|
|||
export const InspectModeController: React.FunctionComponent<{
|
||||
iframe: HTMLIFrameElement | null,
|
||||
isInspecting: boolean,
|
||||
sdkLanguage: Language,
|
||||
testIdAttributeName: string,
|
||||
highlightedLocator: string,
|
||||
setHighlightedLocator: (locator: string) => void,
|
||||
iteration: number,
|
||||
}> = ({ iframe, isInspecting, sdkLanguage, testIdAttributeName, highlightedLocator, setHighlightedLocator, iteration }) => {
|
||||
}> = ({ iframe, isInspecting, testIdAttributeName, highlightedLocator, setHighlightedLocator, iteration }) => {
|
||||
const { sdkLanguage } = React.useContext(WorkbenchContext);
|
||||
React.useEffect(() => {
|
||||
const recorders: { recorder: Recorder, frameSelector: string }[] = [];
|
||||
const isUnderTest = new URLSearchParams(window.location.search).get('isUnderTest') === 'true';
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ import { FilmStrip } from './filmStrip';
|
|||
import type { FilmStripPreviewPoint } from './filmStrip';
|
||||
import type { ActionTraceEventInContext, MultiTraceModel } from './modelUtil';
|
||||
import './timeline.css';
|
||||
import type { Language } from '@isomorphic/locatorGenerators';
|
||||
import type { Entry } from '@trace/har';
|
||||
import { WorkbenchContext } from './workbenchContext';
|
||||
|
||||
type TimelineBar = {
|
||||
action?: ActionTraceEventInContext;
|
||||
|
|
@ -44,8 +44,8 @@ export const Timeline: React.FunctionComponent<{
|
|||
onSelected: (action: ActionTraceEventInContext) => void,
|
||||
selectedTime: Boundaries | undefined,
|
||||
setSelectedTime: (time: Boundaries | undefined) => void,
|
||||
sdkLanguage: Language,
|
||||
}> = ({ model, boundaries, onSelected, highlightedAction, highlightedEntry, selectedTime, setSelectedTime, sdkLanguage }) => {
|
||||
}> = ({ model, boundaries, onSelected, highlightedAction, highlightedEntry, selectedTime, setSelectedTime }) => {
|
||||
const { sdkLanguage } = React.useContext(WorkbenchContext);
|
||||
const [measure, ref] = useMeasure<HTMLDivElement>();
|
||||
const [dragWindow, setDragWindow] = React.useState<{ startX: number, endX: number, pivot?: number, type: 'resize' | 'move' } | undefined>();
|
||||
const [previewPoint, setPreviewPoint] = React.useState<FilmStripPreviewPoint | undefined>();
|
||||
|
|
|
|||
|
|
@ -120,13 +120,10 @@ export const Workbench: React.FunctionComponent<{
|
|||
return model?.actions.map(a => a.attachments || []).flat() || [];
|
||||
}, [model]);
|
||||
|
||||
const sdkLanguage = model?.sdkLanguage || 'javascript';
|
||||
|
||||
const inspectorTab: TabbedPaneTabModel = {
|
||||
id: 'inspector',
|
||||
title: 'Locator',
|
||||
render: () => <InspectorTab
|
||||
sdkLanguage={sdkLanguage}
|
||||
setIsInspecting={setIsInspecting}
|
||||
highlightedLocator={highlightedLocator}
|
||||
setHighlightedLocator={setHighlightedLocator} />,
|
||||
|
|
@ -134,7 +131,7 @@ export const Workbench: React.FunctionComponent<{
|
|||
const callTab: TabbedPaneTabModel = {
|
||||
id: 'call',
|
||||
title: 'Call',
|
||||
render: () => <CallTab action={activeAction} sdkLanguage={sdkLanguage} />
|
||||
render: () => <CallTab action={activeAction} />
|
||||
};
|
||||
const logTab: TabbedPaneTabModel = {
|
||||
id: 'log',
|
||||
|
|
@ -145,7 +142,7 @@ export const Workbench: React.FunctionComponent<{
|
|||
id: 'errors',
|
||||
title: 'Errors',
|
||||
errorCount: errorsModel.errors.size,
|
||||
render: () => <ErrorsTab errorsModel={errorsModel} sdkLanguage={sdkLanguage} revealInSource={error => {
|
||||
render: () => <ErrorsTab errorsModel={errorsModel} revealInSource={error => {
|
||||
if (error.action)
|
||||
setSelectedAction(error.action);
|
||||
else
|
||||
|
|
@ -222,7 +219,6 @@ export const Workbench: React.FunctionComponent<{
|
|||
highlightedAction={highlightedAction}
|
||||
highlightedEntry={highlightedEntry}
|
||||
onSelected={onActionSelected}
|
||||
sdkLanguage={sdkLanguage}
|
||||
selectedTime={selectedTime}
|
||||
setSelectedTime={setSelectedTime}
|
||||
/>
|
||||
|
|
@ -230,7 +226,6 @@ export const Workbench: React.FunctionComponent<{
|
|||
<SplitView sidebarSize={250} orientation='horizontal' sidebarIsFirst={true} settingName='actionListSidebar'>
|
||||
<SnapshotTab
|
||||
action={activeAction}
|
||||
sdkLanguage={sdkLanguage}
|
||||
testIdAttributeName={model?.testIdAttributeName || 'data-testid'}
|
||||
isInspecting={isInspecting}
|
||||
setIsInspecting={setIsInspecting}
|
||||
|
|
@ -250,7 +245,6 @@ export const Workbench: React.FunctionComponent<{
|
|||
<div className='workbench-run-duration'>{time ? msToString(time) : ''}</div>
|
||||
</div>}
|
||||
<ActionList
|
||||
sdkLanguage={sdkLanguage}
|
||||
actions={model?.actions || []}
|
||||
selectedAction={model ? selectedAction : undefined}
|
||||
selectedTime={selectedTime}
|
||||
|
|
|
|||
23
packages/trace-viewer/src/ui/workbenchContext.tsx
Normal file
23
packages/trace-viewer/src/ui/workbenchContext.tsx
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/**
|
||||
* Copyright (c) Microsoft Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import type { Language } from '@isomorphic/locatorGenerators';
|
||||
import { createContext } from 'react';
|
||||
|
||||
type Context = {
|
||||
sdkLanguage: Language,
|
||||
};
|
||||
|
||||
export const WorkbenchContext = createContext<Context>(null as any);
|
||||
|
|
@ -22,6 +22,7 @@ import './workbenchLoader.css';
|
|||
import { toggleTheme } from '@web/theme';
|
||||
import { Workbench } from './workbench';
|
||||
import { TestServerConnection } from '@testIsomorphic/testServerConnection';
|
||||
import { WorkbenchContext } from './workbenchContext';
|
||||
|
||||
export const WorkbenchLoader: React.FunctionComponent<{
|
||||
}> = () => {
|
||||
|
|
@ -165,7 +166,9 @@ export const WorkbenchLoader: React.FunctionComponent<{
|
|||
<div className='progress'>
|
||||
<div className='inner-progress' style={{ width: progress.total ? (100 * progress.done / progress.total) + '%' : 0 }}></div>
|
||||
</div>
|
||||
<Workbench model={model} inert={showFileUploadDropArea} />
|
||||
<WorkbenchContext.Provider value={{ sdkLanguage: model?.sdkLanguage || 'javascript' }}>
|
||||
<Workbench model={model} inert={showFileUploadDropArea} />
|
||||
</WorkbenchContext.Provider>
|
||||
{fileForLocalModeError && <div className='drop-target'>
|
||||
<div>Trace Viewer uses Service Workers to show traces. To view trace:</div>
|
||||
<div style={{ paddingTop: 20 }}>
|
||||
|
|
|
|||
Loading…
Reference in a new issue