cherry-pick(#23148): chore: do not annotate actions after failed ones as timed out
This commit is contained in:
parent
cd94a3f01d
commit
552cba8c05
|
|
@ -76,13 +76,6 @@ export class TraceModel {
|
|||
unzipProgress(++done, total);
|
||||
|
||||
contextEntry.actions = [...actionMap.values()].sort((a1, a2) => a1.startTime - a2.startTime);
|
||||
if (!backend.isLive()) {
|
||||
for (const action of contextEntry.actions) {
|
||||
if (!action.endTime && !action.error)
|
||||
action.error = { name: 'Error', message: 'Timed out' };
|
||||
}
|
||||
}
|
||||
|
||||
const stacks = await this._backend.readText(ordinal + '.stacks');
|
||||
if (stacks) {
|
||||
const callMetadata = parseClientSideCallMetadata(JSON.parse(stacks));
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ export interface ActionListProps {
|
|||
onSelected: (action: ActionTraceEvent) => void,
|
||||
onHighlighted: (action: ActionTraceEvent | undefined) => void,
|
||||
revealConsole: () => void,
|
||||
isLive?: boolean,
|
||||
}
|
||||
|
||||
type ActionTreeItem = {
|
||||
|
|
@ -49,6 +50,7 @@ export const ActionList: React.FC<ActionListProps> = ({
|
|||
onSelected,
|
||||
onHighlighted,
|
||||
revealConsole,
|
||||
isLive,
|
||||
}) => {
|
||||
const [treeState, setTreeState] = React.useState<TreeState>({ expandedItems: new Map() });
|
||||
const { rootItem, itemMap } = React.useMemo(() => {
|
||||
|
|
@ -86,14 +88,15 @@ export const ActionList: React.FC<ActionListProps> = ({
|
|||
onSelected={item => onSelected(item.action!)}
|
||||
onHighlighted={item => onHighlighted(item?.action)}
|
||||
isError={item => !!item.action?.error?.message}
|
||||
render={item => renderAction(item.action!, sdkLanguage, revealConsole)}
|
||||
render={item => renderAction(item.action!, sdkLanguage, revealConsole, isLive || false)}
|
||||
/>;
|
||||
};
|
||||
|
||||
const renderAction = (
|
||||
action: ActionTraceEvent,
|
||||
sdkLanguage: Language | undefined,
|
||||
revealConsole: () => void
|
||||
revealConsole: () => void,
|
||||
isLive: boolean,
|
||||
) => {
|
||||
const { errors, warnings } = modelUtil.stats(action);
|
||||
const locator = action.params.selector ? asLocator(sdkLanguage || 'javascript', action.params.selector, false /* isFrameLocator */, true /* playSafe */) : undefined;
|
||||
|
|
@ -103,6 +106,8 @@ const renderAction = (
|
|||
time = msToString(action.endTime - action.startTime);
|
||||
else if (action.error)
|
||||
time = 'Timed out';
|
||||
else if (!isLive)
|
||||
time = '-';
|
||||
return <>
|
||||
<div className='action-title'>
|
||||
<span>{action.apiName}</span>
|
||||
|
|
|
|||
|
|
@ -492,7 +492,7 @@ const TraceView: React.FC<{
|
|||
item: { testFile?: SourceLocation, testCase?: TestCase },
|
||||
rootDir?: string,
|
||||
}> = ({ item, rootDir }) => {
|
||||
const [model, setModel] = React.useState<MultiTraceModel | undefined>();
|
||||
const [model, setModel] = React.useState<{ model: MultiTraceModel, isLive: boolean } | undefined>();
|
||||
const [counter, setCounter] = React.useState(0);
|
||||
const pollTimer = React.useRef<NodeJS.Timeout | null>(null);
|
||||
|
||||
|
|
@ -505,7 +505,7 @@ const TraceView: React.FC<{
|
|||
// This avoids auto-selection of the last action every time we reload the model.
|
||||
const [selectedActionId, setSelectedActionId] = React.useState<string | undefined>();
|
||||
const onSelectionChanged = React.useCallback((action: ActionTraceEvent) => setSelectedActionId(idForAction(action)), [setSelectedActionId]);
|
||||
const initialSelection = selectedActionId ? model?.actions.find(a => idForAction(a) === selectedActionId) : undefined;
|
||||
const initialSelection = selectedActionId ? model?.model.actions.find(a => idForAction(a) === selectedActionId) : undefined;
|
||||
|
||||
React.useEffect(() => {
|
||||
if (pollTimer.current)
|
||||
|
|
@ -520,7 +520,7 @@ const TraceView: React.FC<{
|
|||
// Test finished.
|
||||
const attachment = result && result.duration >= 0 && result.attachments.find(a => a.name === 'trace');
|
||||
if (attachment && attachment.path) {
|
||||
loadSingleTraceFile(attachment.path).then(model => setModel(model));
|
||||
loadSingleTraceFile(attachment.path).then(model => setModel({ model, isLive: false }));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -534,7 +534,7 @@ const TraceView: React.FC<{
|
|||
pollTimer.current = setTimeout(async () => {
|
||||
try {
|
||||
const model = await loadSingleTraceFile(traceLocation);
|
||||
setModel(model);
|
||||
setModel({ model, isLive: true });
|
||||
} catch {
|
||||
setModel(undefined);
|
||||
} finally {
|
||||
|
|
@ -549,14 +549,15 @@ const TraceView: React.FC<{
|
|||
|
||||
return <Workbench
|
||||
key='workbench'
|
||||
model={model}
|
||||
model={model?.model}
|
||||
hideTimelineBars={true}
|
||||
hideStackFrames={true}
|
||||
showSourcesFirst={true}
|
||||
rootDir={rootDir}
|
||||
initialSelection={initialSelection}
|
||||
onSelectionChanged={onSelectionChanged}
|
||||
fallbackLocation={item.testFile} />;
|
||||
fallbackLocation={item.testFile}
|
||||
isLive={model?.isLive} />;
|
||||
};
|
||||
|
||||
declare global {
|
||||
|
|
|
|||
|
|
@ -41,7 +41,8 @@ export const Workbench: React.FunctionComponent<{
|
|||
fallbackLocation?: modelUtil.SourceLocation,
|
||||
initialSelection?: ActionTraceEvent,
|
||||
onSelectionChanged?: (action: ActionTraceEvent) => void,
|
||||
}> = ({ model, hideTimelineBars, hideStackFrames, showSourcesFirst, rootDir, fallbackLocation, initialSelection, onSelectionChanged }) => {
|
||||
isLive?: boolean,
|
||||
}> = ({ model, hideTimelineBars, hideStackFrames, showSourcesFirst, rootDir, fallbackLocation, initialSelection, onSelectionChanged, isLive }) => {
|
||||
const [selectedAction, setSelectedAction] = React.useState<ActionTraceEvent | undefined>(undefined);
|
||||
const [highlightedAction, setHighlightedAction] = React.useState<ActionTraceEvent | undefined>();
|
||||
const [selectedNavigatorTab, setSelectedNavigatorTab] = React.useState<string>('actions');
|
||||
|
|
@ -142,6 +143,7 @@ export const Workbench: React.FunctionComponent<{
|
|||
onSelected={onActionSelected}
|
||||
onHighlighted={setHighlightedAction}
|
||||
revealConsole={() => setSelectedPropertiesTab('console')}
|
||||
isLive={isLive}
|
||||
/>
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -98,9 +98,12 @@ test('should merge screenshot assertions', async ({ runUITest }, testInfo) => {
|
|||
'action list'
|
||||
).toHaveText([
|
||||
/Before Hooks[\d.]+m?s/,
|
||||
/page\.setContent[\d.]+m?s/,
|
||||
/expect\.toHaveScreenshot[\d.]+m?s/,
|
||||
/After Hooks/,
|
||||
/page.setContent[\d.]+m?s/,
|
||||
/expect.toHaveScreenshot[\d.]+m?s/,
|
||||
/After Hooks-/,
|
||||
/fixture: page[\d.]+m?s/,
|
||||
/fixture: context[\d.]+m?s/,
|
||||
/fixture: browser[\d.]+m?s/,
|
||||
]);
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue