show in html reporter
This commit is contained in:
parent
13d305b959
commit
9a9d789e9b
|
|
@ -113,3 +113,11 @@ export const copy = () => {
|
|||
<path d='M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z'></path>
|
||||
</svg>;
|
||||
};
|
||||
|
||||
export const paperclip = () => {
|
||||
return (
|
||||
<svg className='octicon' viewBox='0 0 16 16' width='16' height='16' aria-hidden='true'>
|
||||
<path d='M12.212 3.02a1.753 1.753 0 0 0-2.478.003l-5.83 5.83a3.007 3.007 0 0 0-.88 2.127c0 .795.315 1.551.88 2.116.567.567 1.333.89 2.126.89.79 0 1.548-.321 2.116-.89l5.48-5.48a.75.75 0 0 1 1.061 1.06l-5.48 5.48a4.492 4.492 0 0 1-3.177 1.33c-1.2 0-2.345-.487-3.187-1.33a4.483 4.483 0 0 1-1.32-3.177c0-1.195.475-2.341 1.32-3.186l5.83-5.83a3.25 3.25 0 0 1 5.553 2.297c0 .863-.343 1.691-.953 2.301L7.439 12.39c-.375.377-.884.59-1.416.593a1.998 1.998 0 0 1-1.412-.593 1.992 1.992 0 0 1 0-2.828l5.48-5.48a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-5.48 5.48a.492.492 0 0 0 0 .707.499.499 0 0 0 .352.154.51.51 0 0 0 .356-.154l5.833-5.827a1.755 1.755 0 0 0 0-2.481Z'></path>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -40,7 +40,9 @@ const result: TestResult = {
|
|||
location: { file: 'test.spec.ts', line: 82, column: 0 },
|
||||
steps: [],
|
||||
count: 1,
|
||||
attachments: [],
|
||||
}],
|
||||
attachments: [],
|
||||
}],
|
||||
attachments: [],
|
||||
status: 'passed',
|
||||
|
|
@ -142,6 +144,7 @@ const resultWithAttachment: TestResult = {
|
|||
location: { file: 'test.spec.ts', line: 62, column: 0 },
|
||||
count: 1,
|
||||
steps: [],
|
||||
attachments: [1],
|
||||
}],
|
||||
attachments: [{
|
||||
name: 'first attachment',
|
||||
|
|
@ -183,3 +186,11 @@ test('should correctly render links in attachment name', async ({ mount }) => {
|
|||
await expect(link).toHaveAttribute('href', 'https://github.com/microsoft/playwright/issues/31284');
|
||||
await expect(link).toHaveText('https://github.com/microsoft/playwright/issues/31284');
|
||||
});
|
||||
|
||||
test('should render attachments in step view', async ({ mount }) => {
|
||||
const component = await mount(<TestCaseView projectNames={['chromium', 'webkit']} test={attachmentLinkRenderingTestCase} run={0} anchor=''></TestCaseView>);
|
||||
const steps = component.getByTestId('test-steps-chip');
|
||||
await expect(steps).not.toContainText('attachment with inline link');
|
||||
await steps.getByTitle('1 attachment').click();
|
||||
await expect(steps).toContainText('attachment with inline link');
|
||||
});
|
||||
|
|
|
|||
|
|
@ -62,3 +62,8 @@
|
|||
padding: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.attachments-icon {
|
||||
color: var(--color-fg-muted);
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import * as React from 'react';
|
|||
import { TreeItem } from './treeItem';
|
||||
import { msToString } from './utils';
|
||||
import { AutoChip } from './chip';
|
||||
import * as icons from './icons';
|
||||
import { traceImage } from './images';
|
||||
import { AttachmentLink, generateTraceUrl } from './links';
|
||||
import { statusIcon } from './statusIcon';
|
||||
|
|
@ -188,23 +189,19 @@ const StepTreeItem: React.FC<{
|
|||
depth: number,
|
||||
attachments: TestAttachment[],
|
||||
}> = ({ step, depth, attachments }) => {
|
||||
if (step.category === 'attach') {
|
||||
const attachmentName = step.title.match(/^attach "(.*)"$/)?.[1];
|
||||
const matchingAttachments = attachments.filter(a => a.name === attachmentName);
|
||||
if (matchingAttachments.length === 1) {
|
||||
const [attachment] = matchingAttachments;
|
||||
return <AttachmentLink attachment={attachment} depth={depth} openInNewTab={getAttachmentCategory(attachment) === 'html'} />;
|
||||
}
|
||||
}
|
||||
|
||||
return <TreeItem title={<span>
|
||||
<span style={{ float: 'right' }}>{msToString(step.duration)}</span>
|
||||
{statusIcon(step.error || step.duration === -1 ? 'failed' : 'passed')}
|
||||
<span>{step.title}</span>
|
||||
{step.count > 1 && <> ✕ <span className='test-result-counter'>{step.count}</span></>}
|
||||
{step.location && <span className='test-result-path'>— {step.location.file}:{step.location.line}</span>}
|
||||
</span>} loadChildren={step.steps.length + (step.snippet ? 1 : 0) ? () => {
|
||||
{step.attachments.length > 0 && <span className='attachments-icon' title={`${step.attachments} attachment${step.attachments.length > 1 ? 's' : ''}`}>{icons.paperclip()}</span>}
|
||||
</span>} loadChildren={step.steps.length + step.attachments.length + (step.snippet ? 1 : 0) ? () => {
|
||||
const children = step.steps.map((s, i) => <StepTreeItem key={i} step={s} depth={depth + 1} attachments={attachments}></StepTreeItem>);
|
||||
children.unshift(...step.attachments.map(a => {
|
||||
const attachment = attachments[a];
|
||||
return <AttachmentLink key={`attachment-${a}`} attachment={attachment} depth={depth + 1} openInNewTab={getAttachmentCategory(attachment) === 'html'}/>;
|
||||
}));
|
||||
if (step.snippet)
|
||||
children.unshift(<TestErrorView key='line' error={step.snippet}></TestErrorView>);
|
||||
return children;
|
||||
|
|
|
|||
|
|
@ -109,5 +109,6 @@ export type TestStep = {
|
|||
snippet?: string;
|
||||
error?: string;
|
||||
steps: TestStep[];
|
||||
attachments: number[];
|
||||
count: number;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -484,7 +484,7 @@ class HtmlBuilder {
|
|||
duration: result.duration,
|
||||
startTime: result.startTime.toISOString(),
|
||||
retry: result.retry,
|
||||
steps: dedupeSteps(result.steps).map(s => this._createTestStep(s)),
|
||||
steps: dedupeSteps(result.steps).map(s => this._createTestStep(s, result)),
|
||||
errors: formatResultFailure(test, result, '', true).map(error => error.message),
|
||||
status: result.status,
|
||||
attachments: this._serializeAttachments([
|
||||
|
|
@ -494,21 +494,27 @@ class HtmlBuilder {
|
|||
};
|
||||
}
|
||||
|
||||
private _createTestStep(dedupedStep: DedupedStep): TestStep {
|
||||
private _createTestStep(dedupedStep: DedupedStep, result: TestResultPublic): TestStep {
|
||||
const { step, duration, count } = dedupedStep;
|
||||
const result: TestStep = {
|
||||
const testStep: TestStep = {
|
||||
title: step.title,
|
||||
category: step.category,
|
||||
startTime: step.startTime.toISOString(),
|
||||
duration,
|
||||
steps: dedupeSteps(step.steps).map(s => this._createTestStep(s)),
|
||||
steps: dedupeSteps(step.steps).map(s => this._createTestStep(s, result)),
|
||||
attachments: step.attachments.map(s => {
|
||||
const index = result.attachments.indexOf(s);
|
||||
if (index === -1)
|
||||
throw new Error('Unexpected, attachment not found');
|
||||
return index;
|
||||
}),
|
||||
location: this._relativeLocation(step.location),
|
||||
error: step.error?.message,
|
||||
count
|
||||
};
|
||||
if (result.location)
|
||||
this._stepsInFile.set(result.location.file, result);
|
||||
return result;
|
||||
if (testStep.location)
|
||||
this._stepsInFile.set(testStep.location.file, testStep);
|
||||
return testStep;
|
||||
}
|
||||
|
||||
private _relativeLocation(location: Location | undefined): Location | undefined {
|
||||
|
|
|
|||
Loading…
Reference in a new issue