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/grid/dockerGridFactory": "./lib/grid/dockerGridFactory.js",
|
||||||
"./src/utils/async": "./lib/utils/async.js",
|
"./src/utils/async": "./lib/utils/async.js",
|
||||||
"./src/utils/httpServer": "./lib/utils/httpServer.js",
|
"./src/utils/httpServer": "./lib/utils/httpServer.js",
|
||||||
|
"./src/utils/multimap": "./lib/utils/multimap.js",
|
||||||
"./src/utils/processLauncher": "./lib/utils/processLauncher.js",
|
"./src/utils/processLauncher": "./lib/utils/processLauncher.js",
|
||||||
"./src/utils/registry": "./lib/utils/registry.js",
|
"./src/utils/registry": "./lib/utils/registry.js",
|
||||||
"./src/utils/utils": "./lib/utils/utils.js"
|
"./src/utils/utils": "./lib/utils/utils.js"
|
||||||
|
|
|
||||||
|
|
@ -368,10 +368,6 @@ a.no-decorations {
|
||||||
color: var(--color-fg-muted) !important;
|
color: var(--color-fg-muted) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.color-fg-white {
|
|
||||||
color: white !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.octicon {
|
.octicon {
|
||||||
margin-right: 7px;
|
margin-right: 7px;
|
||||||
flex: none;
|
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>
|
<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>;
|
</svg>;
|
||||||
case 'skipped':
|
case 'skipped':
|
||||||
return <svg className='octicon color-fg-white' viewBox='0 0 16 16' version='1.1' width='16' height='16' aria-hidden='true'>
|
return <svg className='octicon' viewBox='0 0 16 16' version='1.1' width='16' height='16' aria-hidden='true'></svg>;
|
||||||
<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>;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -179,12 +179,10 @@ class HtmlBuilder {
|
||||||
private _reportFolder: string;
|
private _reportFolder: string;
|
||||||
private _tests = new Map<string, JsonTestCase>();
|
private _tests = new Map<string, JsonTestCase>();
|
||||||
private _testPath = new Map<string, string[]>();
|
private _testPath = new Map<string, string[]>();
|
||||||
private _rootDir: string;
|
|
||||||
private _dataFolder: string;
|
private _dataFolder: string;
|
||||||
private _hasTraces = false;
|
private _hasTraces = false;
|
||||||
|
|
||||||
constructor(outputDir: string, rootDir: string) {
|
constructor(outputDir: string, rootDir: string) {
|
||||||
this._rootDir = rootDir;
|
|
||||||
this._reportFolder = path.resolve(process.cwd(), outputDir);
|
this._reportFolder = path.resolve(process.cwd(), outputDir);
|
||||||
this._dataFolder = path.join(this._reportFolder, 'data');
|
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 { FullConfig, Location, Suite, TestCase, TestResult, TestStatus, TestStep } from '../../types/testReporter';
|
||||||
import { assert, calculateSha1 } from 'playwright-core/src/utils/utils';
|
import { assert, calculateSha1 } from 'playwright-core/src/utils/utils';
|
||||||
import { sanitizeForFilePath } from '../util';
|
import { sanitizeForFilePath } from '../util';
|
||||||
import { formatResultFailure, generateCodeFrame } from './base';
|
import { formatResultFailure } from './base';
|
||||||
import { toPosixPath, serializePatterns } from './json';
|
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 JsonLocation = Location;
|
||||||
export type JsonError = string;
|
export type JsonError = string;
|
||||||
|
|
@ -99,6 +101,7 @@ export type JsonTestStep = {
|
||||||
class RawReporter {
|
class RawReporter {
|
||||||
private config!: FullConfig;
|
private config!: FullConfig;
|
||||||
private suite!: Suite;
|
private suite!: Suite;
|
||||||
|
private stepsInFile = new MultiMap<string, JsonTestStep>();
|
||||||
|
|
||||||
onBegin(config: FullConfig, suite: Suite) {
|
onBegin(config: FullConfig, suite: Suite) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
|
|
@ -148,6 +151,31 @@ class RawReporter {
|
||||||
},
|
},
|
||||||
suites: suite.suites.map(s => this._serializeSuite(s))
|
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;
|
return report;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -190,23 +218,24 @@ class RawReporter {
|
||||||
status: result.status,
|
status: result.status,
|
||||||
error: formatResultFailure(test, result, '', true).tokens.join('').trim(),
|
error: formatResultFailure(test, result, '', true).tokens.join('').trim(),
|
||||||
attachments: this._createAttachments(result),
|
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[] {
|
private _serializeStep(test: TestCase, step: TestStep): JsonTestStep {
|
||||||
return steps.map(step => {
|
const result: JsonTestStep = {
|
||||||
return {
|
title: step.title,
|
||||||
title: step.title,
|
category: step.category,
|
||||||
category: step.category,
|
startTime: step.startTime.toISOString(),
|
||||||
startTime: step.startTime.toISOString(),
|
duration: step.duration,
|
||||||
duration: step.duration,
|
error: step.error?.message,
|
||||||
error: step.error?.message,
|
location: this._relativeLocation(step.location),
|
||||||
location: this._relativeLocation(step.location),
|
steps: step.steps.map(step => this._serializeStep(test, step)),
|
||||||
steps: this._serializeSteps(test, step.steps),
|
};
|
||||||
snippet: step.location ? generateCodeFrame({ highlightCode: true, linesBelow: 1, linesAbove: 1 }, step.location.file, step.location) : undefined
|
|
||||||
};
|
if (step.location)
|
||||||
});
|
this.stepsInFile.set(step.location.file, result);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _createAttachments(result: TestResult): JsonAttachment[] {
|
private _createAttachments(result: TestResult): JsonAttachment[] {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue