Skip to content

Commit

Permalink
feat(inspector): collapse completed items (#5484)
Browse files Browse the repository at this point in the history
  • Loading branch information
pavelfeldman committed Feb 18, 2021
1 parent dc51536 commit 3248c24
Show file tree
Hide file tree
Showing 11 changed files with 55 additions and 67 deletions.
1 change: 1 addition & 0 deletions src/server/supplements/recorder/recorderTypes.ts
Expand Up @@ -35,6 +35,7 @@ export type CallLog = {
messages: string[];
status: 'in-progress' | 'done' | 'error' | 'paused';
error?: string;
reveal?: boolean;
};

export type SourceHighlight = {
Expand Down
4 changes: 0 additions & 4 deletions src/web/common.css
Expand Up @@ -81,10 +81,6 @@ body {
display: none !important;
}

.codicon {
color: var(--toolbar-color);
}

svg {
fill: currentColor;
}
Expand Down
6 changes: 3 additions & 3 deletions src/web/components/toolbar.stories.tsx
Expand Up @@ -25,9 +25,9 @@ export default {
} as Meta;

const Template: Story<ToolbarProps> = () => <Toolbar>
<ToolbarButton icon="clone" title="Copy" onClick={() => {}}></ToolbarButton>
<ToolbarButton icon="trashcan" title="Erase" onClick={() => {}}></ToolbarButton>
<ToolbarButton icon="close" title="Close" onClick={() => {}}></ToolbarButton>
<ToolbarButton icon='record' title='Record' onClick={() => {}}>Record</ToolbarButton>
<ToolbarButton icon='question' title='Inspect' onClick={() => {}}>Explore</ToolbarButton>
<ToolbarButton icon='files' title='Copy' onClick={() => {}}></ToolbarButton>
</Toolbar>;

export const Primary = Template.bind({});
Expand Down
22 changes: 5 additions & 17 deletions src/web/components/toolbarButton.css
Expand Up @@ -22,31 +22,19 @@
padding: 0;
margin-left: 10px;
cursor: pointer;
display: flex;
align-items: center;
}

.toolbar-button:disabled {
color: #bbb !important;
cursor: default;
}

.toolbar-button:not(.disabled):hover {
.toolbar-button:not(.disabled):not(.toggled):hover {
color: #555;
}

.toolbar-button.toggled {
color: #1ea7fd;
}

.toolbar-button.codicon-record.toggled {
color: #fd1e1e;
}

.toolbar-button.codicon-debug-continue,
.toolbar-button.codicon-debug-step-over {
color: #01bb01;
}

.toolbar-button.codicon-debug-continue:hover,
.toolbar-button.codicon-debug-step-over:hover {
color: #41ca1e;
.toolbar-button .codicon {
margin-right: 4px;
}
5 changes: 3 additions & 2 deletions src/web/components/toolbarButton.tsx
Expand Up @@ -27,14 +27,15 @@ export interface ToolbarButtonProps {
}

export const ToolbarButton: React.FC<ToolbarButtonProps> = ({
children,
title = '',
icon = '',
disabled = false,
toggled = false,
onClick = () => {},
}) => {
let className = `toolbar-button codicon codicon-${icon}`;
let className = `toolbar-button ${icon}`;
if (toggled)
className += ' toggled';
return <button className={className} onClick={onClick} title={title} disabled={!!disabled}></button>;
return <button className={className} onClick={onClick} title={title} disabled={!!disabled}><span className={`codicon codicon-${icon}`}></span>{ children }</button>;
};
2 changes: 1 addition & 1 deletion src/web/recorder/callLog.example.ts
Expand Up @@ -50,7 +50,7 @@ export function exampleCallLog(): CallLog[] {
'status': 'paused'
},
{
'id': 5,
'id': 6,
'messages': [
'navigating to "https://github.com/microsoft", waiting until "load"',
],
Expand Down
22 changes: 16 additions & 6 deletions src/web/recorder/callLog.tsx
Expand Up @@ -23,27 +23,37 @@ export interface CallLogProps {
}

export const CallLogView: React.FC<CallLogProps> = ({
log
log,
}) => {
const messagesEndRef = React.createRef<HTMLDivElement>();
const [expandOverrides, setExpandOverrides] = React.useState<Map<number, boolean>>(new Map());
React.useLayoutEffect(() => {
messagesEndRef.current?.scrollIntoView({ block: 'center', inline: 'nearest' });
if (log.find(callLog => callLog.reveal))
messagesEndRef.current?.scrollIntoView({ block: 'center', inline: 'nearest' });
}, [messagesEndRef]);

return <div className='vbox'>
<div className='call-log-header' style={{flex: 'none'}}>Log</div>
<div className='call-log' style={{flex: 'auto'}}>
{log.map(callLog => {
const expandOverride = expandOverrides.get(callLog.id);
const isExpanded = typeof expandOverride === 'boolean' ? expandOverride : callLog.status !== 'done';
return <div className={`call-log-call ${callLog.status}`} key={callLog.id}>
<div className='call-log-call-header'>
<span className={'codicon ' + iconClass(callLog)}></span>{ callLog.title }
<span className={`codicon codicon-chevron-${isExpanded ? 'down' : 'right'}`} style={{ cursor: 'pointer' }}onClick={() => {
const newOverrides = new Map(expandOverrides);
newOverrides.set(callLog.id, !isExpanded);
setExpandOverrides(newOverrides);
}}></span>
{ callLog.title }
<span className={'codicon ' + iconClass(callLog)}></span>
</div>
{ callLog.messages.map((message, i) => {
{ (isExpanded ? callLog.messages : []).map((message, i) => {
return <div className='call-log-message' key={i}>
{ message.trim() }
</div>;
})}
{ callLog.error ? <div className='call-log-message error'>
{ callLog.error ? <div className='call-log-message error' hidden={!isExpanded}>
{ callLog.error }
</div> : undefined }
</div>
Expand Down
4 changes: 3 additions & 1 deletion src/web/recorder/main.tsx
Expand Up @@ -42,8 +42,10 @@ export const Main: React.FC = ({
window.playwrightSetPaused = setPaused;
window.playwrightUpdateLogs = callLogs => {
const newLog = new Map<number, CallLog>(log);
for (const callLog of callLogs)
for (const callLog of callLogs) {
callLog.reveal = !log.has(callLog.id);
newLog.set(callLog.id, callLog);
}
setLog(newLog);
};

Expand Down
18 changes: 18 additions & 0 deletions src/web/recorder/recorder.css
Expand Up @@ -37,3 +37,21 @@
color: var(--toolbar-color);
margin-left: 16px;
}

.recorder .toolbar-button.toggled.question {
color: #12a3ff;
}

.recorder .toolbar-button.toggled.record {
color: #fd1e1e;
}

.recorder .toolbar-button:not([disabled]) .codicon-debug-continue,
.recorder .toolbar-button:not([disabled]) .codicon-debug-step-over {
color: #01bb01;
}

.recorder .toolbar-button:not([disabled]):hover .codicon-debug-continue,
.recorder .toolbar-button:not([disabled]):hover .codicon-debug-step-over {
color: #41ca1e;
}
11 changes: 5 additions & 6 deletions src/web/recorder/recorder.tsx
Expand Up @@ -57,15 +57,14 @@ export const Recorder: React.FC<RecorderProps> = ({
React.useLayoutEffect(() => {
messagesEndRef.current?.scrollIntoView({ block: 'center', inline: 'nearest' });
}, [messagesEndRef]);

return <div className='recorder'>
<Toolbar>
<ToolbarButton icon='record' title='Record' toggled={mode == 'recording'} onClick={() => {
window.dispatch({ event: 'setMode', params: { mode: mode === 'recording' ? 'none' : 'recording' }}).catch(() => { });
}}></ToolbarButton>
<ToolbarButton icon='question' title='Inspect' toggled={mode == 'inspecting'} onClick={() => {
}}>Record</ToolbarButton>
<ToolbarButton icon='question' title='Explore' toggled={mode == 'inspecting'} onClick={() => {
window.dispatch({ event: 'setMode', params: { mode: mode === 'inspecting' ? 'none' : 'inspecting' }}).catch(() => { });
}}></ToolbarButton>
}}>Explore</ToolbarButton>
<ToolbarButton icon='files' title='Copy' disabled={!source || !source.text} onClick={() => {
copy(source.text);
}}></ToolbarButton>
Expand All @@ -78,12 +77,12 @@ export const Recorder: React.FC<RecorderProps> = ({
<ToolbarButton icon='debug-step-over' title='Step over' disabled={!paused} onClick={() => {
window.dispatch({ event: 'step' }).catch(() => {});
}}></ToolbarButton>
<select className='recorder-chooser' hidden={!sources.length} onChange={event => {
<select className='recorder-chooser' hidden={!sources.length} value={file} onChange={event => {
setFile(event.target.selectedOptions[0].value);
}}>{
sources.map(s => {
const title = s.file.replace(/.*[/\\]([^/\\]+)/, '$1');
return <option key={s.file} value={s.file} selected={s.file === file}>{title}</option>;
return <option key={s.file} value={s.file}>{title}</option>;
})
}
</select>
Expand Down
27 changes: 0 additions & 27 deletions test/pause.spec.ts
Expand Up @@ -148,19 +148,6 @@ describe('pause', (suite, { mode }) => {
expect(await sanitizeLog(recorderPage)).toEqual([
'pause',
'click',
'waiting for selector "button"',
'selector resolved to visible <button>Submit</button>',
'attempting click action',
'waiting for element to be visible, enabled and stable',
'element is visible, enabled and stable',
'scrolling into view if needed',
'done scrolling',
'checking that element receives pointer events at ()',
'element does receive pointer events',
'performing click action',
'click action done',
'waiting for scheduled navigations to finish',
'navigations have finished',
'pause',
]);
await recorderPage.click('[title="Resume"]');
Expand All @@ -183,21 +170,7 @@ describe('pause', (suite, { mode }) => {
expect(await sanitizeLog(recorderPage)).toEqual([
'pause',
'waitForEvent()',
'waiting for event \"console\"',
'click',
'waiting for selector "button"',
'selector resolved to visible <button onclick=\"console.log()\">Submit</button>',
'attempting click action',
'waiting for element to be visible, enabled and stable',
'element is visible, enabled and stable',
'scrolling into view if needed',
'done scrolling',
'checking that element receives pointer events at ()',
'element does receive pointer events',
'performing click action',
'click action done',
'waiting for scheduled navigations to finish',
'navigations have finished',
'pause',
]);
await recorderPage.click('[title="Resume"]');
Expand Down

0 comments on commit 3248c24

Please sign in to comment.