chore: speed up snippet generation 50 times (#9638)
This commit is contained in:
parent
9578cda79a
commit
4423de9996
|
|
@ -25,6 +25,7 @@
|
|||
"./src/grid/dockerGridFactory": "./lib/grid/dockerGridFactory.js",
|
||||
"./src/utils/async": "./lib/utils/async.js",
|
||||
"./src/utils/httpServer": "./lib/utils/httpServer.js",
|
||||
"./src/utils/multimap": "./lib/utils/multimap.js",
|
||||
"./src/utils/processLauncher": "./lib/utils/processLauncher.js",
|
||||
"./src/utils/registry": "./lib/utils/registry.js",
|
||||
"./src/utils/utils": "./lib/utils/utils.js"
|
||||
|
|
|
|||
|
|
@ -368,10 +368,6 @@ a.no-decorations {
|
|||
color: var(--color-fg-muted) !important;
|
||||
}
|
||||
|
||||
.color-fg-white {
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
.octicon {
|
||||
margin-right: 7px;
|
||||
flex: none;
|
||||
|
|
|
|||
|
|
@ -303,9 +303,7 @@ function statusIcon(status: 'failed' | 'timedOut' | 'skipped' | 'passed' | 'expe
|
|||
<path fillRule='evenodd' d='M8.22 1.754a.25.25 0 00-.44 0L1.698 13.132a.25.25 0 00.22.368h12.164a.25.25 0 00.22-.368L8.22 1.754zm-1.763-.707c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0114.082 15H1.918a1.75 1.75 0 01-1.543-2.575L6.457 1.047zM9 11a1 1 0 11-2 0 1 1 0 012 0zm-.25-5.25a.75.75 0 00-1.5 0v2.5a.75.75 0 001.5 0v-2.5z'></path>
|
||||
</svg>;
|
||||
case 'skipped':
|
||||
return <svg className='octicon color-fg-white' viewBox='0 0 16 16' version='1.1' width='16' height='16' aria-hidden='true'>
|
||||
<path fillRule='evenodd' d='M1.5 8a6.5 6.5 0 1113 0 6.5 6.5 0 01-13 0zM8 0a8 8 0 100 16A8 8 0 008 0zm3.28 5.78a.75.75 0 00-1.06-1.06l-5.5 5.5a.75.75 0 101.06 1.06l5.5-5.5z'></path>
|
||||
</svg>;
|
||||
return <svg className='octicon' viewBox='0 0 16 16' version='1.1' width='16' height='16' aria-hidden='true'></svg>;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -179,12 +179,10 @@ class HtmlBuilder {
|
|||
private _reportFolder: string;
|
||||
private _tests = new Map<string, JsonTestCase>();
|
||||
private _testPath = new Map<string, string[]>();
|
||||
private _rootDir: string;
|
||||
private _dataFolder: string;
|
||||
private _hasTraces = false;
|
||||
|
||||
constructor(outputDir: string, rootDir: string) {
|
||||
this._rootDir = rootDir;
|
||||
this._reportFolder = path.resolve(process.cwd(), outputDir);
|
||||
this._dataFolder = path.join(this._reportFolder, 'data');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,10 @@ import path from 'path';
|
|||
import { FullConfig, Location, Suite, TestCase, TestResult, TestStatus, TestStep } from '../../types/testReporter';
|
||||
import { assert, calculateSha1 } from 'playwright-core/src/utils/utils';
|
||||
import { sanitizeForFilePath } from '../util';
|
||||
import { formatResultFailure, generateCodeFrame } from './base';
|
||||
import { formatResultFailure } from './base';
|
||||
import { toPosixPath, serializePatterns } from './json';
|
||||
import { MultiMap } from 'playwright-core/src/utils/multimap';
|
||||
import { codeFrameColumns } from '@babel/code-frame';
|
||||
|
||||
export type JsonLocation = Location;
|
||||
export type JsonError = string;
|
||||
|
|
@ -99,6 +101,7 @@ export type JsonTestStep = {
|
|||
class RawReporter {
|
||||
private config!: FullConfig;
|
||||
private suite!: Suite;
|
||||
private stepsInFile = new MultiMap<string, JsonTestStep>();
|
||||
|
||||
onBegin(config: FullConfig, suite: Suite) {
|
||||
this.config = config;
|
||||
|
|
@ -148,6 +151,31 @@ class RawReporter {
|
|||
},
|
||||
suites: suite.suites.map(s => this._serializeSuite(s))
|
||||
};
|
||||
for (const file of this.stepsInFile.keys()) {
|
||||
let source: string;
|
||||
try {
|
||||
source = fs.readFileSync(file, 'utf-8') + '\n//';
|
||||
} catch (e) {
|
||||
continue;
|
||||
}
|
||||
const lines = source.split('\n').length;
|
||||
const highlighted = codeFrameColumns(source, { start: { line: lines, column: 1 } }, { highlightCode: true, linesAbove: lines, linesBelow: 0 });
|
||||
const highlightedLines = highlighted.split('\n');
|
||||
const lineWithArrow = highlightedLines[highlightedLines.length - 1];
|
||||
for (const step of this.stepsInFile.get(file)) {
|
||||
// Don't bother with snippets that have less than 3 lines.
|
||||
if (step.location!.line < 2 || step.location!.line >= lines)
|
||||
continue;
|
||||
// Cut out snippet.
|
||||
const snippetLines = highlightedLines.slice(step.location!.line - 2, step.location!.line + 1);
|
||||
// Relocate arrow.
|
||||
const index = lineWithArrow.indexOf('^');
|
||||
const shiftedArrow = lineWithArrow.slice(0, index) + ' '.repeat(step.location!.column - 1) + lineWithArrow.slice(index);
|
||||
// Insert arrow line.
|
||||
snippetLines.splice(2, 0, shiftedArrow);
|
||||
step.snippet = snippetLines.join('\n');
|
||||
}
|
||||
}
|
||||
return report;
|
||||
}
|
||||
|
||||
|
|
@ -190,23 +218,24 @@ class RawReporter {
|
|||
status: result.status,
|
||||
error: formatResultFailure(test, result, '', true).tokens.join('').trim(),
|
||||
attachments: this._createAttachments(result),
|
||||
steps: this._serializeSteps(test, result.steps)
|
||||
steps: result.steps.map(step => this._serializeStep(test, step))
|
||||
};
|
||||
}
|
||||
|
||||
private _serializeSteps(test: TestCase, steps: TestStep[]): JsonTestStep[] {
|
||||
return steps.map(step => {
|
||||
return {
|
||||
title: step.title,
|
||||
category: step.category,
|
||||
startTime: step.startTime.toISOString(),
|
||||
duration: step.duration,
|
||||
error: step.error?.message,
|
||||
location: this._relativeLocation(step.location),
|
||||
steps: this._serializeSteps(test, step.steps),
|
||||
snippet: step.location ? generateCodeFrame({ highlightCode: true, linesBelow: 1, linesAbove: 1 }, step.location.file, step.location) : undefined
|
||||
};
|
||||
});
|
||||
private _serializeStep(test: TestCase, step: TestStep): JsonTestStep {
|
||||
const result: JsonTestStep = {
|
||||
title: step.title,
|
||||
category: step.category,
|
||||
startTime: step.startTime.toISOString(),
|
||||
duration: step.duration,
|
||||
error: step.error?.message,
|
||||
location: this._relativeLocation(step.location),
|
||||
steps: step.steps.map(step => this._serializeStep(test, step)),
|
||||
};
|
||||
|
||||
if (step.location)
|
||||
this.stepsInFile.set(step.location.file, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private _createAttachments(result: TestResult): JsonAttachment[] {
|
||||
|
|
|
|||
Loading…
Reference in a new issue