chore: speed up snippet generation 50 times (#9638)

This commit is contained in:
Pavel Feldman 2021-10-19 20:10:14 -08:00 committed by GitHub
parent 9578cda79a
commit 4423de9996
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 46 additions and 24 deletions

View file

@ -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"

View file

@ -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;

View file

@ -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>;
}
}

View file

@ -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');
}

View file

@ -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 {
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: this._serializeSteps(test, step.steps),
snippet: step.location ? generateCodeFrame({ highlightCode: true, linesBelow: 1, linesAbove: 1 }, step.location.file, step.location) : undefined
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[] {