mirror of
https://github.com/microsoft/playwright.git
synced 2024-10-27 13:50:25 +03:00
chore: hide timeline bars and stack from ui mode (#21590)
This commit is contained in:
parent
ea8aa63f1a
commit
428ea66578
@ -19,6 +19,7 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
min-height: 50px;
|
||||
}
|
||||
|
||||
.film-strip-lane {
|
||||
|
@ -30,7 +30,8 @@ type StackInfo = {
|
||||
|
||||
export const SourceTab: React.FunctionComponent<{
|
||||
action: ActionTraceEvent | undefined,
|
||||
}> = ({ action }) => {
|
||||
hideStackFrames?: boolean,
|
||||
}> = ({ action, hideStackFrames }) => {
|
||||
const [lastAction, setLastAction] = React.useState<ActionTraceEvent | undefined>();
|
||||
const [selectedFrame, setSelectedFrame] = React.useState<number>(0);
|
||||
|
||||
@ -69,7 +70,7 @@ export const SourceTab: React.FunctionComponent<{
|
||||
|
||||
const targetLine = stackInfo.frames[selectedFrame]?.line || 0;
|
||||
const error = action?.error?.message;
|
||||
return <SplitView sidebarSize={200} orientation='horizontal'>
|
||||
return <SplitView sidebarSize={200} orientation='horizontal' sidebarHidden={hideStackFrames}>
|
||||
<CodeMirrorWrapper text={content} language='javascript' highlight={[{ line: targetLine, type: error ? 'error' : 'running', message: error }]} revealLine={targetLine} readOnly={true} lineNumbers={true}></CodeMirrorWrapper>
|
||||
<StackTraceView action={action} selectedFrame={selectedFrame} setSelectedFrame={setSelectedFrame}></StackTraceView>
|
||||
</SplitView>;
|
||||
|
@ -41,7 +41,8 @@ export const Timeline: React.FunctionComponent<{
|
||||
model: MultiTraceModel | undefined,
|
||||
selectedAction: ActionTraceEvent | undefined,
|
||||
onSelected: (action: ActionTraceEvent) => void,
|
||||
}> = ({ model, selectedAction, onSelected }) => {
|
||||
hideTimelineBars?: boolean,
|
||||
}> = ({ model, selectedAction, onSelected, hideTimelineBars }) => {
|
||||
const [measure, ref] = useMeasure<HTMLDivElement>();
|
||||
const barsRef = React.useRef<HTMLDivElement | null>(null);
|
||||
|
||||
@ -50,6 +51,10 @@ export const Timeline: React.FunctionComponent<{
|
||||
|
||||
const { boundaries, offsets } = React.useMemo(() => {
|
||||
const boundaries = { minimum: model?.startTime || 0, maximum: model?.endTime || 30000 };
|
||||
if (boundaries.minimum > boundaries.maximum) {
|
||||
boundaries.minimum = 0;
|
||||
boundaries.maximum = 30000;
|
||||
}
|
||||
// Leave some nice free space on the right hand side.
|
||||
boundaries.maximum += (boundaries.maximum - boundaries.minimum) / 20;
|
||||
return { boundaries, offsets: calculateDividerOffsets(measure.width, boundaries) };
|
||||
@ -95,41 +100,34 @@ export const Timeline: React.FunctionComponent<{
|
||||
let targetBar: TimelineBar | undefined = bars.find(bar => bar.action === selectedAction);
|
||||
targetBar = hoveredBar || targetBar;
|
||||
|
||||
const findHoveredBarIndex = (x: number, y: number) => {
|
||||
const findHoveredBarIndex = (x: number) => {
|
||||
const time = positionToTime(measure.width, boundaries, x);
|
||||
const time1 = positionToTime(measure.width, boundaries, x - 5);
|
||||
const time2 = positionToTime(measure.width, boundaries, x + 5);
|
||||
let index: number | undefined;
|
||||
let yDistance: number | undefined;
|
||||
let xDistance: number | undefined;
|
||||
for (let i = 0; i < bars.length; i++) {
|
||||
const bar = bars[i];
|
||||
const yMiddle = kBarHeight / 2 + barTop(bar);
|
||||
const left = Math.max(bar.leftTime, time1);
|
||||
const right = Math.min(bar.rightTime, time2);
|
||||
const xMiddle = (bar.leftTime + bar.rightTime) / 2;
|
||||
const xd = Math.abs(time - xMiddle);
|
||||
const yd = Math.abs(y - yMiddle);
|
||||
if (left > right)
|
||||
continue;
|
||||
// Prefer closest yDistance (the same bar), among those prefer the closest xDistance.
|
||||
if (index === undefined ||
|
||||
(yd < yDistance!) ||
|
||||
(Math.abs(yd - yDistance!) < 1e-2 && xd < xDistance!)) {
|
||||
if (index === undefined || xd < xDistance!) {
|
||||
index = i;
|
||||
xDistance = xd;
|
||||
yDistance = yd;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
};
|
||||
|
||||
const onMouseMove = (event: React.MouseEvent) => {
|
||||
if (!ref.current || !barsRef.current)
|
||||
if (!ref.current)
|
||||
return;
|
||||
const x = event.clientX - ref.current.getBoundingClientRect().left;
|
||||
const y = event.clientY - barsRef.current.getBoundingClientRect().top;
|
||||
const index = findHoveredBarIndex(x, y);
|
||||
const index = findHoveredBarIndex(x);
|
||||
setPreviewPoint({ x, clientY: event.clientY });
|
||||
setHoveredBarIndex(index);
|
||||
};
|
||||
@ -141,11 +139,10 @@ export const Timeline: React.FunctionComponent<{
|
||||
|
||||
const onClick = (event: React.MouseEvent) => {
|
||||
setPreviewPoint(undefined);
|
||||
if (!ref.current || !barsRef.current)
|
||||
if (!ref.current)
|
||||
return;
|
||||
const x = event.clientX - ref.current.getBoundingClientRect().left;
|
||||
const y = event.clientY - barsRef.current.getBoundingClientRect().top;
|
||||
const index = findHoveredBarIndex(x, y);
|
||||
const index = findHoveredBarIndex(x);
|
||||
if (index === undefined)
|
||||
return;
|
||||
const entry = bars[index].action;
|
||||
@ -162,7 +159,7 @@ export const Timeline: React.FunctionComponent<{
|
||||
</div>;
|
||||
})
|
||||
}</div>
|
||||
<div className='timeline-lane timeline-labels'>{
|
||||
{!hideTimelineBars && <div className='timeline-lane timeline-labels'>{
|
||||
bars.map((bar, index) => {
|
||||
return <div key={index}
|
||||
className={'timeline-label ' + bar.className + (targetBar === bar ? ' selected' : '')}
|
||||
@ -174,8 +171,8 @@ export const Timeline: React.FunctionComponent<{
|
||||
{bar.label}
|
||||
</div>;
|
||||
})
|
||||
}</div>
|
||||
<div className='timeline-lane timeline-bars' ref={barsRef}>{
|
||||
}</div>}
|
||||
{!hideTimelineBars && <div className='timeline-lane timeline-bars' ref={barsRef}>{
|
||||
bars.map((bar, index) => {
|
||||
return <div key={index}
|
||||
className={'timeline-bar ' + (bar.action ? 'action ' : '') + (bar.event ? 'event ' : '') + bar.className + (targetBar === bar ? ' selected' : '')}
|
||||
@ -187,7 +184,7 @@ export const Timeline: React.FunctionComponent<{
|
||||
title={bar.title}
|
||||
></div>;
|
||||
})
|
||||
}</div>
|
||||
}</div>}
|
||||
<FilmStrip model={model} boundaries={boundaries} previewPoint={previewPoint} />
|
||||
<div className='timeline-marker timeline-marker-hover' style={{
|
||||
display: (previewPoint !== undefined) ? 'block' : 'none',
|
||||
@ -239,7 +236,6 @@ function trimRight(s: string, maxLength: number): string {
|
||||
return s.length <= maxLength ? s : s.substring(0, maxLength - 1) + '\u2026';
|
||||
}
|
||||
|
||||
const kBarHeight = 11;
|
||||
function barTop(bar: TimelineBar): number {
|
||||
return bar.event ? 22 : (bar.action?.method === 'waitForEventInfo' ? 0 : 11);
|
||||
}
|
||||
|
@ -346,7 +346,7 @@ export const TraceView: React.FC<{
|
||||
const xterm = <XtermWrapper source={xtermDataSource}></XtermWrapper>;
|
||||
return <Workbench model={model} output={xterm} rightToolbar={[
|
||||
<ToolbarButton icon='trash' title='Clear output' onClick={() => xtermDataSource.clear()}></ToolbarButton>,
|
||||
]}/>;
|
||||
]} hideTimelineBars={true} hideStackFrames={true} />;
|
||||
};
|
||||
|
||||
declare global {
|
||||
|
@ -35,7 +35,9 @@ export const Workbench: React.FunctionComponent<{
|
||||
model?: MultiTraceModel,
|
||||
output?: React.ReactElement,
|
||||
rightToolbar?: React.ReactElement[],
|
||||
}> = ({ model, output, rightToolbar }) => {
|
||||
hideTimelineBars?: boolean,
|
||||
hideStackFrames?: boolean,
|
||||
}> = ({ model, output, rightToolbar, hideTimelineBars, hideStackFrames }) => {
|
||||
const [selectedAction, setSelectedAction] = React.useState<ActionTraceEvent | undefined>(undefined);
|
||||
const [highlightedAction, setHighlightedAction] = React.useState<ActionTraceEvent | undefined>();
|
||||
const [selectedNavigatorTab, setSelectedNavigatorTab] = React.useState<string>('actions');
|
||||
@ -49,7 +51,7 @@ export const Workbench: React.FunctionComponent<{
|
||||
if (failedAction)
|
||||
setSelectedAction(failedAction);
|
||||
// In the UI mode, selecting the first error should reveal source.
|
||||
if (output)
|
||||
if (failedAction && output)
|
||||
setSelectedPropertiesTab('source');
|
||||
}, [model, output, selectedAction, setSelectedAction, setSelectedPropertiesTab]);
|
||||
|
||||
@ -60,7 +62,7 @@ export const Workbench: React.FunctionComponent<{
|
||||
|
||||
const tabs: TabbedPaneTabModel[] = [
|
||||
{ id: 'call', title: 'Call', render: () => <CallTab action={activeAction} sdkLanguage={sdkLanguage} /> },
|
||||
{ id: 'source', title: 'Source', count: 0, render: () => <SourceTab action={activeAction} /> },
|
||||
{ id: 'source', title: 'Source', count: 0, render: () => <SourceTab action={activeAction} hideStackFrames={hideStackFrames}/> },
|
||||
{ id: 'console', title: 'Console', count: consoleCount, render: () => <ConsoleTab action={activeAction} /> },
|
||||
{ id: 'network', title: 'Network', count: networkCount, render: () => <NetworkTab action={activeAction} /> },
|
||||
];
|
||||
@ -73,6 +75,7 @@ export const Workbench: React.FunctionComponent<{
|
||||
model={model}
|
||||
selectedAction={activeAction}
|
||||
onSelected={action => setSelectedAction(action)}
|
||||
hideTimelineBars={hideTimelineBars}
|
||||
/>
|
||||
<SplitView sidebarSize={output ? 250 : 350} orientation={output ? 'vertical' : 'horizontal'}>
|
||||
<SplitView sidebarSize={250} orientation='horizontal' sidebarIsFirst={true}>
|
||||
|
Loading…
Reference in New Issue
Block a user