chore: iterate towards tele reporter reuse in vscode (2) (#29812)
This commit is contained in:
parent
5eb8fea616
commit
e314b83e56
|
|
@ -122,10 +122,9 @@ export type JsonEvent = {
|
||||||
};
|
};
|
||||||
|
|
||||||
type TeleReporterReceiverOptions = {
|
type TeleReporterReceiverOptions = {
|
||||||
pathSeparator: string;
|
|
||||||
mergeProjects: boolean;
|
mergeProjects: boolean;
|
||||||
mergeTestCases: boolean;
|
mergeTestCases: boolean;
|
||||||
internString?: StringIntern;
|
resolvePath: (rootDir: string, relativePath: string) => string;
|
||||||
configOverrides?: Pick<reporterTypes.FullConfig, 'configFile' | 'quiet' | 'reportSlowTests' | 'reporter'>;
|
configOverrides?: Pick<reporterTypes.FullConfig, 'configFile' | 'quiet' | 'reportSlowTests' | 'reporter'>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -242,7 +241,6 @@ export class TeleReporterReceiver {
|
||||||
testResult.workerIndex = payload.workerIndex;
|
testResult.workerIndex = payload.workerIndex;
|
||||||
testResult.parallelIndex = payload.parallelIndex;
|
testResult.parallelIndex = payload.parallelIndex;
|
||||||
testResult.setStartTimeNumber(payload.startTime);
|
testResult.setStartTimeNumber(payload.startTime);
|
||||||
testResult.statusEx = 'running';
|
|
||||||
this._reporter.onTestBegin?.(test, testResult);
|
this._reporter.onTestBegin?.(test, testResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -251,22 +249,21 @@ export class TeleReporterReceiver {
|
||||||
test.timeout = testEndPayload.timeout;
|
test.timeout = testEndPayload.timeout;
|
||||||
test.expectedStatus = testEndPayload.expectedStatus;
|
test.expectedStatus = testEndPayload.expectedStatus;
|
||||||
test.annotations = testEndPayload.annotations;
|
test.annotations = testEndPayload.annotations;
|
||||||
const result = test.resultsMap.get(payload.id)!;
|
const result = test._resultsMap.get(payload.id)!;
|
||||||
result.duration = payload.duration;
|
result.duration = payload.duration;
|
||||||
result.status = payload.status;
|
result.status = payload.status;
|
||||||
result.statusEx = payload.status;
|
|
||||||
result.errors = payload.errors;
|
result.errors = payload.errors;
|
||||||
result.error = result.errors?.[0];
|
result.error = result.errors?.[0];
|
||||||
result.attachments = this._parseAttachments(payload.attachments);
|
result.attachments = this._parseAttachments(payload.attachments);
|
||||||
this._reporter.onTestEnd?.(test, result);
|
this._reporter.onTestEnd?.(test, result);
|
||||||
// Free up the memory as won't see these step ids.
|
// Free up the memory as won't see these step ids.
|
||||||
result.stepMap = new Map();
|
result._stepMap = new Map();
|
||||||
}
|
}
|
||||||
|
|
||||||
private _onStepBegin(testId: string, resultId: string, payload: JsonTestStepStart) {
|
private _onStepBegin(testId: string, resultId: string, payload: JsonTestStepStart) {
|
||||||
const test = this._tests.get(testId)!;
|
const test = this._tests.get(testId)!;
|
||||||
const result = test.resultsMap.get(resultId)!;
|
const result = test._resultsMap.get(resultId)!;
|
||||||
const parentStep = payload.parentStepId ? result.stepMap.get(payload.parentStepId) : undefined;
|
const parentStep = payload.parentStepId ? result._stepMap.get(payload.parentStepId) : undefined;
|
||||||
|
|
||||||
const location = this._absoluteLocation(payload.location);
|
const location = this._absoluteLocation(payload.location);
|
||||||
const step = new TeleTestStep(payload, parentStep, location);
|
const step = new TeleTestStep(payload, parentStep, location);
|
||||||
|
|
@ -274,14 +271,14 @@ export class TeleReporterReceiver {
|
||||||
parentStep.steps.push(step);
|
parentStep.steps.push(step);
|
||||||
else
|
else
|
||||||
result.steps.push(step);
|
result.steps.push(step);
|
||||||
result.stepMap.set(payload.id, step);
|
result._stepMap.set(payload.id, step);
|
||||||
this._reporter.onStepBegin?.(test, result, step);
|
this._reporter.onStepBegin?.(test, result, step);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _onStepEnd(testId: string, resultId: string, payload: JsonTestStepEnd) {
|
private _onStepEnd(testId: string, resultId: string, payload: JsonTestStepEnd) {
|
||||||
const test = this._tests.get(testId)!;
|
const test = this._tests.get(testId)!;
|
||||||
const result = test.resultsMap.get(resultId)!;
|
const result = test._resultsMap.get(resultId)!;
|
||||||
const step = result.stepMap.get(payload.id)!;
|
const step = result._stepMap.get(payload.id)!;
|
||||||
step.duration = payload.duration;
|
step.duration = payload.duration;
|
||||||
step.error = payload.error;
|
step.error = payload.error;
|
||||||
this._reporter.onStepEnd?.(test, result, step);
|
this._reporter.onStepEnd?.(test, result, step);
|
||||||
|
|
@ -294,7 +291,7 @@ export class TeleReporterReceiver {
|
||||||
private _onStdIO(type: JsonStdIOType, testId: string | undefined, resultId: string | undefined, data: string, isBase64: boolean) {
|
private _onStdIO(type: JsonStdIOType, testId: string | undefined, resultId: string | undefined, data: string, isBase64: boolean) {
|
||||||
const chunk = isBase64 ? ((globalThis as any).Buffer ? Buffer.from(data, 'base64') : atob(data)) : data;
|
const chunk = isBase64 ? ((globalThis as any).Buffer ? Buffer.from(data, 'base64') : atob(data)) : data;
|
||||||
const test = testId ? this._tests.get(testId) : undefined;
|
const test = testId ? this._tests.get(testId) : undefined;
|
||||||
const result = test && resultId ? test.resultsMap.get(resultId) : undefined;
|
const result = test && resultId ? test._resultsMap.get(resultId) : undefined;
|
||||||
if (type === 'stdout') {
|
if (type === 'stdout') {
|
||||||
result?.stdout.push(chunk);
|
result?.stdout.push(chunk);
|
||||||
this._reporter.onStdOut?.(chunk, test, result);
|
this._reporter.onStdOut?.(chunk, test, result);
|
||||||
|
|
@ -407,11 +404,7 @@ export class TeleReporterReceiver {
|
||||||
private _absolutePath(relativePath?: string): string | undefined {
|
private _absolutePath(relativePath?: string): string | undefined {
|
||||||
if (relativePath === undefined)
|
if (relativePath === undefined)
|
||||||
return;
|
return;
|
||||||
return this._internString(this._rootDir + this._options.pathSeparator + relativePath);
|
return this._options.resolvePath(this._rootDir, relativePath);
|
||||||
}
|
|
||||||
|
|
||||||
private _internString(s: string): string {
|
|
||||||
return this._options.internString ? this._options.internString(s) : s;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -475,7 +468,7 @@ export class TeleTestCase implements reporterTypes.TestCase {
|
||||||
repeatEachIndex = 0;
|
repeatEachIndex = 0;
|
||||||
id: string;
|
id: string;
|
||||||
|
|
||||||
resultsMap = new Map<string, TeleTestResult>();
|
_resultsMap = new Map<string, TeleTestResult>();
|
||||||
|
|
||||||
constructor(id: string, title: string, location: reporterTypes.Location, repeatEachIndex: number) {
|
constructor(id: string, title: string, location: reporterTypes.Location, repeatEachIndex: number) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
|
|
@ -515,13 +508,13 @@ export class TeleTestCase implements reporterTypes.TestCase {
|
||||||
|
|
||||||
_clearResults() {
|
_clearResults() {
|
||||||
this.results = [];
|
this.results = [];
|
||||||
this.resultsMap.clear();
|
this._resultsMap.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
_createTestResult(id: string): TeleTestResult {
|
_createTestResult(id: string): TeleTestResult {
|
||||||
const result = new TeleTestResult(this.results.length);
|
const result = new TeleTestResult(this.results.length);
|
||||||
this.results.push(result);
|
this.results.push(result);
|
||||||
this.resultsMap.set(id, result);
|
this._resultsMap.set(id, result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -571,8 +564,7 @@ class TeleTestResult implements reporterTypes.TestResult {
|
||||||
errors: reporterTypes.TestResult['errors'] = [];
|
errors: reporterTypes.TestResult['errors'] = [];
|
||||||
error: reporterTypes.TestResult['error'];
|
error: reporterTypes.TestResult['error'];
|
||||||
|
|
||||||
stepMap: Map<string, reporterTypes.TestStep> = new Map();
|
_stepMap: Map<string, reporterTypes.TestStep> = new Map();
|
||||||
statusEx: reporterTypes.TestResult['status'] | 'scheduled' | 'running' = 'scheduled';
|
|
||||||
|
|
||||||
private _startTime: number = 0;
|
private _startTime: number = 0;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ export class BlobReporter extends TeleReporterEmitter {
|
||||||
private _reportName!: string;
|
private _reportName!: string;
|
||||||
|
|
||||||
constructor(options: BlobReporterOptions) {
|
constructor(options: BlobReporterOptions) {
|
||||||
super(message => this._messages.push(message), false);
|
super(message => this._messages.push(message));
|
||||||
this._options = options;
|
this._options = options;
|
||||||
if (this._options.fileName && !this._options.fileName.endsWith('.zip'))
|
if (this._options.fileName && !this._options.fileName.endsWith('.zip'))
|
||||||
throw new Error(`Blob report file name must end with .zip extension: ${this._options.fileName}`);
|
throw new Error(`Blob report file name must end with .zip extension: ${this._options.fileName}`);
|
||||||
|
|
|
||||||
|
|
@ -54,10 +54,9 @@ export async function createMergedReport(config: FullConfigInternal, dir: string
|
||||||
// If explicit config is provided, use platform path separator, otherwise use the one from the report (if any).
|
// If explicit config is provided, use platform path separator, otherwise use the one from the report (if any).
|
||||||
const pathSeparator = rootDirOverride ? path.sep : (eventData.pathSeparatorFromMetadata ?? path.sep);
|
const pathSeparator = rootDirOverride ? path.sep : (eventData.pathSeparatorFromMetadata ?? path.sep);
|
||||||
const receiver = new TeleReporterReceiver(multiplexer, {
|
const receiver = new TeleReporterReceiver(multiplexer, {
|
||||||
pathSeparator,
|
|
||||||
mergeProjects: false,
|
mergeProjects: false,
|
||||||
mergeTestCases: false,
|
mergeTestCases: false,
|
||||||
internString: s => stringPool.internString(s),
|
resolvePath: (rootDir, relativePath) => stringPool.internString(rootDir + pathSeparator + relativePath),
|
||||||
configOverrides: config.config,
|
configOverrides: config.config,
|
||||||
});
|
});
|
||||||
printStatus(`processing test events`);
|
printStatus(`processing test events`);
|
||||||
|
|
|
||||||
|
|
@ -21,14 +21,19 @@ import type * as teleReceiver from '../isomorphic/teleReceiver';
|
||||||
import { serializeRegexPatterns } from '../isomorphic/teleReceiver';
|
import { serializeRegexPatterns } from '../isomorphic/teleReceiver';
|
||||||
import type { ReporterV2 } from './reporterV2';
|
import type { ReporterV2 } from './reporterV2';
|
||||||
|
|
||||||
|
export type TeleReporterEmitterOptions = {
|
||||||
|
omitOutput?: boolean;
|
||||||
|
omitBuffers?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
export class TeleReporterEmitter implements ReporterV2 {
|
export class TeleReporterEmitter implements ReporterV2 {
|
||||||
private _messageSink: (message: teleReceiver.JsonEvent) => void;
|
private _messageSink: (message: teleReceiver.JsonEvent) => void;
|
||||||
private _rootDir!: string;
|
private _rootDir!: string;
|
||||||
private _skipBuffers: boolean;
|
private _emitterOptions: TeleReporterEmitterOptions;
|
||||||
|
|
||||||
constructor(messageSink: (message: teleReceiver.JsonEvent) => void, skipBuffers: boolean) {
|
constructor(messageSink: (message: teleReceiver.JsonEvent) => void, options: TeleReporterEmitterOptions = {}) {
|
||||||
this._messageSink = messageSink;
|
this._messageSink = messageSink;
|
||||||
this._skipBuffers = skipBuffers;
|
this._emitterOptions = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
version(): 'v2' {
|
version(): 'v2' {
|
||||||
|
|
@ -113,6 +118,8 @@ export class TeleReporterEmitter implements ReporterV2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
private _onStdIO(type: teleReceiver.JsonStdIOType, chunk: string | Buffer, test: void | reporterTypes.TestCase, result: void | reporterTypes.TestResult): void {
|
private _onStdIO(type: teleReceiver.JsonStdIOType, chunk: string | Buffer, test: void | reporterTypes.TestCase, result: void | reporterTypes.TestResult): void {
|
||||||
|
if (this._emitterOptions.omitOutput)
|
||||||
|
return;
|
||||||
const isBase64 = typeof chunk !== 'string';
|
const isBase64 = typeof chunk !== 'string';
|
||||||
const data = isBase64 ? chunk.toString('base64') : chunk;
|
const data = isBase64 ? chunk.toString('base64') : chunk;
|
||||||
this._messageSink({
|
this._messageSink({
|
||||||
|
|
@ -224,7 +231,7 @@ export class TeleReporterEmitter implements ReporterV2 {
|
||||||
return {
|
return {
|
||||||
...a,
|
...a,
|
||||||
// There is no Buffer in the browser, so there is no point in sending the data there.
|
// There is no Buffer in the browser, so there is no point in sending the data there.
|
||||||
base64: (a.body && !this._skipBuffers) ? a.body.toString('base64') : undefined,
|
base64: (a.body && !this._emitterOptions.omitBuffers) ? a.body.toString('base64') : undefined,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ export async function createReporterForTestServer(config: FullConfigInternal, fi
|
||||||
function reporterOptions(config: FullConfigInternal, mode: 'list' | 'test' | 'ui' | 'merge', send?: (message: any) => void) {
|
function reporterOptions(config: FullConfigInternal, mode: 'list' | 'test' | 'ui' | 'merge', send?: (message: any) => void) {
|
||||||
return {
|
return {
|
||||||
configDir: config.configDir,
|
configDir: config.configDir,
|
||||||
send,
|
_send: send,
|
||||||
_mode: mode,
|
_mode: mode,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -114,13 +114,13 @@ class Dispatcher implements TestServerInterface {
|
||||||
async listTests(params: {
|
async listTests(params: {
|
||||||
configFile: string;
|
configFile: string;
|
||||||
locations: string[];
|
locations: string[];
|
||||||
reporters: { file: string, event: string }[];
|
reporter: string;
|
||||||
env: NodeJS.ProcessEnv;
|
env: NodeJS.ProcessEnv;
|
||||||
}) {
|
}) {
|
||||||
const config = await this._loadConfig(params.configFile);
|
const config = await this._loadConfig(params.configFile);
|
||||||
config.cliArgs = params.locations || [];
|
config.cliArgs = params.locations || [];
|
||||||
const wireReporters = await this._wireReporters(config, 'list', params.reporters);
|
const wireReporter = await createReporterForTestServer(config, params.reporter, 'list', message => this._dispatchEvent('report', message));
|
||||||
const reporter = new InternalReporter(new Multiplexer(wireReporters));
|
const reporter = new InternalReporter(new Multiplexer([wireReporter]));
|
||||||
const taskRunner = createTaskRunnerForList(config, reporter, 'out-of-process', { failOnLoadErrors: true });
|
const taskRunner = createTaskRunnerForList(config, reporter, 'out-of-process', { failOnLoadErrors: true });
|
||||||
const testRun = new TestRun(config, reporter);
|
const testRun = new TestRun(config, reporter);
|
||||||
reporter.onConfigure(config.config);
|
reporter.onConfigure(config.config);
|
||||||
|
|
@ -138,7 +138,7 @@ class Dispatcher implements TestServerInterface {
|
||||||
async test(params: {
|
async test(params: {
|
||||||
configFile: string;
|
configFile: string;
|
||||||
locations: string[];
|
locations: string[];
|
||||||
reporters: { file: string, event: string }[];
|
reporter: string;
|
||||||
env: NodeJS.ProcessEnv;
|
env: NodeJS.ProcessEnv;
|
||||||
headed?: boolean;
|
headed?: boolean;
|
||||||
oneWorker?: boolean;
|
oneWorker?: boolean;
|
||||||
|
|
@ -169,9 +169,9 @@ class Dispatcher implements TestServerInterface {
|
||||||
config.cliGrep = params.grep;
|
config.cliGrep = params.grep;
|
||||||
config.cliProjectFilter = params.projects?.length ? params.projects : undefined;
|
config.cliProjectFilter = params.projects?.length ? params.projects : undefined;
|
||||||
|
|
||||||
const wireReporters = await this._wireReporters(config, 'test', params.reporters);
|
const wireReporter = await createReporterForTestServer(config, params.reporter, 'test', message => this._dispatchEvent('report', message));
|
||||||
const configReporters = await createReporters(config, 'test');
|
const configReporters = await createReporters(config, 'test');
|
||||||
const reporter = new InternalReporter(new Multiplexer([...configReporters, ...wireReporters]));
|
const reporter = new InternalReporter(new Multiplexer([...configReporters, wireReporter]));
|
||||||
const taskRunner = createTaskRunnerForTestServer(config, reporter);
|
const taskRunner = createTaskRunnerForTestServer(config, reporter);
|
||||||
const testRun = new TestRun(config, reporter);
|
const testRun = new TestRun(config, reporter);
|
||||||
reporter.onConfigure(config.config);
|
reporter.onConfigure(config.config);
|
||||||
|
|
@ -186,14 +186,6 @@ class Dispatcher implements TestServerInterface {
|
||||||
await run;
|
await run;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _wireReporters(config: FullConfigInternal, mode: 'test' | 'list', reporters: { file: string, event: string }[]) {
|
|
||||||
return await Promise.all(reporters.map(r => {
|
|
||||||
return createReporterForTestServer(config, r.file, mode, message => {
|
|
||||||
this._dispatchEvent(r.event, message);
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
async findRelatedTestFiles(params: {
|
async findRelatedTestFiles(params: {
|
||||||
configFile: string;
|
configFile: string;
|
||||||
files: string[];
|
files: string[];
|
||||||
|
|
|
||||||
|
|
@ -33,13 +33,13 @@ export interface TestServerInterface {
|
||||||
listTests(params: {
|
listTests(params: {
|
||||||
configFile: string;
|
configFile: string;
|
||||||
locations: string[];
|
locations: string[];
|
||||||
reporters: { file: string, event: string }[];
|
reporter: string;
|
||||||
}): Promise<void>;
|
}): Promise<void>;
|
||||||
|
|
||||||
test(params: {
|
test(params: {
|
||||||
configFile: string;
|
configFile: string;
|
||||||
locations: string[];
|
locations: string[];
|
||||||
reporters: { file: string, event: string }[];
|
reporter: string;
|
||||||
headed?: boolean;
|
headed?: boolean;
|
||||||
oneWorker?: boolean;
|
oneWorker?: boolean;
|
||||||
trace?: 'on' | 'off';
|
trace?: 'on' | 'off';
|
||||||
|
|
|
||||||
|
|
@ -167,7 +167,7 @@ class UIMode {
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _listTests() {
|
private async _listTests() {
|
||||||
const reporter = new InternalReporter(new TeleReporterEmitter(e => this._dispatchEvent('listReport', e), true));
|
const reporter = new InternalReporter(new TeleReporterEmitter(e => this._dispatchEvent('listReport', e), { omitBuffers: true }));
|
||||||
this._config.cliListOnly = true;
|
this._config.cliListOnly = true;
|
||||||
this._config.testIdMatcher = undefined;
|
this._config.testIdMatcher = undefined;
|
||||||
const taskRunner = createTaskRunnerForList(this._config, reporter, 'out-of-process', { failOnLoadErrors: false });
|
const taskRunner = createTaskRunnerForList(this._config, reporter, 'out-of-process', { failOnLoadErrors: false });
|
||||||
|
|
@ -195,7 +195,7 @@ class UIMode {
|
||||||
this._config.testIdMatcher = id => !testIdSet || testIdSet.has(id);
|
this._config.testIdMatcher = id => !testIdSet || testIdSet.has(id);
|
||||||
|
|
||||||
const reporters = await createReporters(this._config, 'ui');
|
const reporters = await createReporters(this._config, 'ui');
|
||||||
reporters.push(new TeleReporterEmitter(e => this._dispatchEvent('testReport', e), true));
|
reporters.push(new TeleReporterEmitter(e => this._dispatchEvent('testReport', e), { omitBuffers: true }));
|
||||||
const reporter = new InternalReporter(new Multiplexer(reporters));
|
const reporter = new InternalReporter(new Multiplexer(reporters));
|
||||||
const taskRunner = createTaskRunnerForWatch(this._config, reporter);
|
const taskRunner = createTaskRunnerForWatch(this._config, reporter);
|
||||||
const testRun = new TestRun(this._config, reporter);
|
const testRun = new TestRun(this._config, reporter);
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ import { TreeView } from '@web/components/treeView';
|
||||||
import type { TreeState } from '@web/components/treeView';
|
import type { TreeState } from '@web/components/treeView';
|
||||||
import { baseFullConfig, TeleReporterReceiver, TeleSuite } from '@testIsomorphic/teleReceiver';
|
import { baseFullConfig, TeleReporterReceiver, TeleSuite } from '@testIsomorphic/teleReceiver';
|
||||||
import type { TeleTestCase } from '@testIsomorphic/teleReceiver';
|
import type { TeleTestCase } from '@testIsomorphic/teleReceiver';
|
||||||
import type { FullConfig, Suite, TestCase, Location, TestError } from 'playwright/types/testReporter';
|
import type { FullConfig, Suite, TestCase, Location, TestError, TestResult } from 'playwright/types/testReporter';
|
||||||
import { SplitView } from '@web/components/splitView';
|
import { SplitView } from '@web/components/splitView';
|
||||||
import { idForAction, MultiTraceModel } from './modelUtil';
|
import { idForAction, MultiTraceModel } from './modelUtil';
|
||||||
import type { SourceLocation } from './modelUtil';
|
import type { SourceLocation } from './modelUtil';
|
||||||
|
|
@ -151,7 +151,8 @@ export const UIModeView: React.FC<{}> = ({
|
||||||
for (const test of testModel.rootSuite?.allTests() || []) {
|
for (const test of testModel.rootSuite?.allTests() || []) {
|
||||||
if (testIds.has(test.id)) {
|
if (testIds.has(test.id)) {
|
||||||
(test as TeleTestCase)._clearResults();
|
(test as TeleTestCase)._clearResults();
|
||||||
(test as TeleTestCase)._createTestResult('pending');
|
const result = (test as TeleTestCase)._createTestResult('pending');
|
||||||
|
(result as any)[statusEx] = 'scheduled';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setTestModel({ ...testModel });
|
setTestModel({ ...testModel });
|
||||||
|
|
@ -655,9 +656,9 @@ const refreshRootSuite = (eraseResults: boolean): Promise<void> => {
|
||||||
lastRunReceiver = undefined;
|
lastRunReceiver = undefined;
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
pathSeparator,
|
|
||||||
mergeProjects: true,
|
mergeProjects: true,
|
||||||
mergeTestCases: false
|
mergeTestCases: false,
|
||||||
|
resolvePath: (rootDir, relativePath) => rootDir + pathSeparator + relativePath,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -675,17 +676,19 @@ const refreshRootSuite = (eraseResults: boolean): Promise<void> => {
|
||||||
throttleUpdateRootSuite(config, rootSuite, loadErrors, progress, true);
|
throttleUpdateRootSuite(config, rootSuite, loadErrors, progress, true);
|
||||||
},
|
},
|
||||||
|
|
||||||
onTestBegin: () => {
|
onTestBegin: (test: TestCase, testResult: TestResult) => {
|
||||||
|
(testResult as any)[statusEx] = 'running';
|
||||||
throttleUpdateRootSuite(config, rootSuite, loadErrors, progress);
|
throttleUpdateRootSuite(config, rootSuite, loadErrors, progress);
|
||||||
},
|
},
|
||||||
|
|
||||||
onTestEnd: (test: TestCase) => {
|
onTestEnd: (test: TestCase, testResult: TestResult) => {
|
||||||
if (test.outcome() === 'skipped')
|
if (test.outcome() === 'skipped')
|
||||||
++progress.skipped;
|
++progress.skipped;
|
||||||
else if (test.outcome() === 'unexpected')
|
else if (test.outcome() === 'unexpected')
|
||||||
++progress.failed;
|
++progress.failed;
|
||||||
else
|
else
|
||||||
++progress.passed;
|
++progress.passed;
|
||||||
|
(testResult as any)[statusEx] = testResult.status;
|
||||||
throttleUpdateRootSuite(config, rootSuite, loadErrors, progress);
|
throttleUpdateRootSuite(config, rootSuite, loadErrors, progress);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -705,9 +708,9 @@ const refreshRootSuite = (eraseResults: boolean): Promise<void> => {
|
||||||
onStepBegin: () => {},
|
onStepBegin: () => {},
|
||||||
onStepEnd: () => {},
|
onStepEnd: () => {},
|
||||||
}, {
|
}, {
|
||||||
pathSeparator,
|
|
||||||
mergeProjects: true,
|
mergeProjects: true,
|
||||||
mergeTestCases: true,
|
mergeTestCases: true,
|
||||||
|
resolvePath: (rootDir, relativePath) => rootDir + pathSeparator + relativePath,
|
||||||
});
|
});
|
||||||
receiver._setClearPreviousResultsWhenTestBegins();
|
receiver._setClearPreviousResultsWhenTestBegins();
|
||||||
return sendMessage('list', {});
|
return sendMessage('list', {});
|
||||||
|
|
@ -906,11 +909,11 @@ function createTree(rootSuite: Suite | undefined, loadErrors: TestError[], proje
|
||||||
parentGroup.children.push(testCaseItem);
|
parentGroup.children.push(testCaseItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = (test as TeleTestCase).results[0];
|
const result = test.results[0];
|
||||||
let status: 'none' | 'running' | 'scheduled' | 'passed' | 'failed' | 'skipped' = 'none';
|
let status: 'none' | 'running' | 'scheduled' | 'passed' | 'failed' | 'skipped' = 'none';
|
||||||
if (result?.statusEx === 'scheduled')
|
if ((result as any)?.[statusEx] === 'scheduled')
|
||||||
status = 'scheduled';
|
status = 'scheduled';
|
||||||
else if (result?.statusEx === 'running')
|
else if ((result as any)?.[statusEx] === 'running')
|
||||||
status = 'running';
|
status = 'running';
|
||||||
else if (result?.status === 'skipped')
|
else if (result?.status === 'skipped')
|
||||||
status = 'skipped';
|
status = 'skipped';
|
||||||
|
|
@ -1053,3 +1056,4 @@ async function loadSingleTraceFile(url: string): Promise<MultiTraceModel> {
|
||||||
}
|
}
|
||||||
|
|
||||||
const pathSeparator = navigator.userAgent.toLowerCase().includes('windows') ? '\\' : '/';
|
const pathSeparator = navigator.userAgent.toLowerCase().includes('windows') ? '\\' : '/';
|
||||||
|
const statusEx = Symbol('statusEx');
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue