chore: render time in the trace viewer log (#27825)

This commit is contained in:
Pavel Feldman 2023-10-26 14:45:15 -07:00 committed by GitHub
parent 89e0978da4
commit ff206bd9c1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 79 additions and 12 deletions

View File

@ -0,0 +1,31 @@
/**
* 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.
*/
.log-list-duration {
display: flex;
flex: none;
align-items: center;
color: var(--vscode-editorCodeLens-foreground);
float: right;
margin-right: 5px;
user-select: none;
}
.log-list-item {
text-wrap: wrap;
user-select: text;
width: 100%;
}

View File

@ -18,17 +18,51 @@ import type { ActionTraceEventInContext } from './modelUtil';
import * as React from 'react';
import { ListView } from '@web/components/listView';
import { PlaceholderPanel } from './placeholderPanel';
import { msToString } from '@web/uiUtils';
import './logTab.css';
const LogList = ListView<{ message: string, time: number }>;
const LogList = ListView<{ message: string, time: string }>;
export const LogTab: React.FunctionComponent<{
action: ActionTraceEventInContext | undefined,
}> = ({ action }) => {
if (!action?.log.length)
isLive: boolean | undefined,
}> = ({ action, isLive }) => {
const entries = React.useMemo(() => {
if (!action || !action.log.length)
return [];
const log = action.log;
const wallTimeOffset = action.wallTime - action.startTime;
const entries: { message: string, time: string }[] = [];
for (let i = 0; i < log.length; ++i) {
let time = '';
if (log[i].time !== -1) {
const timeStart = log[i]?.time;
if (i + 1 < log.length)
time = msToString(log[i + 1].time - timeStart);
else if (action.endTime > 0)
time = msToString(action.endTime - timeStart);
else if (isLive)
time = msToString(Date.now() - wallTimeOffset - timeStart);
else
time = '-';
}
entries.push({
message: log[i].message,
time,
});
}
return entries;
}, [action]);
if (!entries.length)
return <PlaceholderPanel text='No log entries' />;
return <LogList
name='log'
items={action?.log || []}
render={logLine => logLine.message}
items={entries}
render={entry => <div className='log-list-item'>
<span className='log-list-duration'>{entry.time}</span>
{entry.message}
</div>}
noHighlightOnHover={true}
/>;
};

View File

@ -131,7 +131,7 @@ export const Workbench: React.FunctionComponent<{
const logTab: TabbedPaneTabModel = {
id: 'log',
title: 'Log',
render: () => <LogTab action={activeAction} />
render: () => <LogTab action={activeAction} isLive={isLive} />
};
const errorsTab: TabbedPaneTabModel = {
id: 'errors',
@ -199,7 +199,7 @@ export const Workbench: React.FunctionComponent<{
}, [model]);
let time: number = 0;
if (model && model.endTime >= 0)
if (!isLive && model && model.endTime >= 0)
time = model.endTime - model.startTime;
else if (model && model.wallTime)
time = Date.now() - model.wallTime;

View File

@ -35,6 +35,7 @@ export type ListViewProps<T> = {
onIconClicked?: (item: T, index: number) => void,
noItemsMessage?: string,
dataTestId?: string,
noHighlightOnHover?: boolean,
};
const scrollPositions = new Map<string, number>();
@ -57,6 +58,7 @@ export function ListView<T>({
onIconClicked,
noItemsMessage,
dataTestId,
noHighlightOnHover,
}: ListViewProps<T>) {
const itemListRef = React.useRef<HTMLDivElement>(null);
const [highlightedItem, setHighlightedItem] = React.useState<any>();
@ -131,7 +133,7 @@ export function ListView<T>({
{noItemsMessage && items.length === 0 && <div className='list-view-empty'>{noItemsMessage}</div>}
{items.map((item, index) => {
const selectedSuffix = selectedItem === item ? ' selected' : '';
const highlightedSuffix = highlightedItem === item ? ' highlighted' : '';
const highlightedSuffix = !noHighlightOnHover && highlightedItem === item ? ' highlighted' : '';
const errorSuffix = isError?.(item, index) ? ' error' : '';
const warningSuffix = isWarning?.(item, index) ? ' warning' : '';
const indentation = indent?.(item, index) || 0;

View File

@ -123,10 +123,10 @@ test('should contain action info', async ({ showTraceViewer }) => {
const traceViewer = await showTraceViewer([traceFile]);
await traceViewer.selectAction('locator.click');
await traceViewer.page.getByText('Log', { exact: true }).click();
const logLines = await traceViewer.logLines.allTextContents();
expect(logLines.length).toBeGreaterThan(10);
expect(logLines).toContain('attempting click action');
expect(logLines).toContain(' click action done');
await expect(traceViewer.logLines).toContainText([
/\d+m?sattempting click action/,
/\d+m?s click action done/,
]);
});
test('should render network bars', async ({ page, runAndTrace, server }) => {