Skip to content

Commit

Permalink
feat(test-runner): implement basic allure reporter
Browse files Browse the repository at this point in the history
  • Loading branch information
pavelfeldman committed Jul 16, 2021
1 parent 8b2dd2e commit 372cbf5
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 2 deletions.
10 changes: 9 additions & 1 deletion src/test/expect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ function toMatchSnapshot(this: ReturnType<Expect['getState']>, received: Buffer
options.threshold = projectThreshold;

const withNegateComparison = this.isNot;
const { pass, message } = compare(
const { pass, message, expectedPath, actualPath, diffPath, mimeType } = compare(
received,
options.name,
testInfo.snapshotPath,
Expand All @@ -47,6 +47,14 @@ function toMatchSnapshot(this: ReturnType<Expect['getState']>, received: Buffer
withNegateComparison,
options
);
if (expectedPath) {
testInfo.data['toMatchSnapshot'] = {
expectedPath,
actualPath,
diffPath,
mimeType
};
}
return { pass, message: () => message };
}

Expand Down
6 changes: 5 additions & 1 deletion src/test/golden.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export function compare(
updateSnapshots: UpdateSnapshots,
withNegateComparison: boolean,
options?: { threshold?: number }
): { pass: boolean; message?: string; } {
): { pass: boolean; message?: string; expectedPath?: string, actualPath?: string, diffPath?: string, mimeType?: string } {
const snapshotFile = snapshotPath(name);

if (!fs.existsSync(snapshotFile)) {
Expand Down Expand Up @@ -179,6 +179,10 @@ export function compare(
return {
pass: false,
message: output.join('\n'),
expectedPath,
actualPath,
diffPath,
mimeType
};
}

Expand Down
122 changes: 122 additions & 0 deletions src/test/reporters/allure.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/**
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { AllureGroup, AllureRuntime, LabelName, Status } from 'allure-js-commons';
import path from 'path';
import { FullConfig, Suite, Test, TestStatus } from '../reporter';
import { stripAscii } from './base';
import EmptyReporter from './empty';

const startTimeSymbol = Symbol('startTime');

class AllureReporter extends EmptyReporter {
config!: FullConfig;
suite!: Suite;

onBegin(config: FullConfig, suite: Suite) {
this.config = config;
this.suite = suite;
}

onTestBegin(test: Test) {
(test.results[test.results.length - 1] as any)[startTimeSymbol] = Date.now();
}

onTimeout() {
this.onEnd();
}

async onEnd() {
const resultsDir = path.join(process.cwd(), 'allure-results');
const runtime = new AllureRuntime({resultsDir});
const processSuite = (suite: Suite, parent: AllureGroup | AllureRuntime, groupNamePath: string[]) => {
let groupName = 'Root';
if (suite.file) {
// TODO: use suite's project
const project = this.config.projects[0];
const groupName = suite.title || path.relative(project.testDir, suite.file);
groupNamePath = [...groupNamePath, groupName];
}
const group = parent.startGroup(groupName);
for (const test of suite.tests) {
for (const result of test.results) {
const startTime = (result as any)[startTimeSymbol];
const endTime = startTime + result.duration;

const allureTest = group.startTest(test.fullTitle(), startTime);
const [parentSuite, suite, ...subSuites] = groupNamePath;
if (parentSuite)
allureTest.addLabel(LabelName.PARENT_SUITE, parentSuite);
if (suite)
allureTest.addLabel(LabelName.SUITE, suite);
if (subSuites.length > 0)
allureTest.addLabel(LabelName.SUB_SUITE, subSuites.join(" > "));

allureTest.historyId = test.fullTitle();
allureTest.fullName = test.fullTitle();
allureTest.status = statusToAllureStats(result.status!);

if (result.error) {
const message = result.error.message && stripAscii(result.error.message);
let trace = result.error.stack && stripAscii(result.error.stack);
if (trace && message && trace.startsWith(message))
trace = trace.substr(message.length);
allureTest.statusDetails = {
message,
trace,
};
}

if (test.projectName)
allureTest.addParameter('project', test.projectName);

if (result.data['toMatchSnapshot']) {
const { expectedPath, actualPath, diffPath, mimeType } = result.data['toMatchSnapshot'];
allureTest.addLabel('testType', 'screenshotDiff');
allureTest.addAttachment('expected', mimeType, expectedPath);
allureTest.addAttachment('actual', mimeType, actualPath);
allureTest.addAttachment('diff', mimeType, diffPath);
}

for (const stdout of result.stdout)
allureTest.addAttachment('stdout', 'text/plain', runtime.writeAttachment(stdout, 'text/plain'));
for (const stderr of result.stderr)
allureTest.addAttachment('stderr', 'text/plain', runtime.writeAttachment(stderr, 'text/plain'));
allureTest.endTest(endTime);
}
}
for (const child of suite.suites)
processSuite(child, group, groupNamePath);
group.endGroup();
};
processSuite(this.suite, runtime, []);
}
}

function statusToAllureStats(status: TestStatus): Status {
switch (status) {
case 'failed':
return Status.FAILED;
case 'passed':
return Status.PASSED;
case 'skipped':
return Status.SKIPPED;
case 'timedOut':
return Status.BROKEN;
}
}

export default AllureReporter;
2 changes: 2 additions & 0 deletions src/test/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { Test, Suite } from './test';
import { Loader } from './loader';
import { Reporter } from './reporter';
import { Multiplexer } from './reporters/multiplexer';
import AllureReporter from './reporters/allure';
import DotReporter from './reporters/dot';
import LineReporter from './reporters/line';
import ListReporter from './reporters/list';
Expand Down Expand Up @@ -65,6 +66,7 @@ export class Runner {
private async _createReporter() {
const reporters: Reporter[] = [];
const defaultReporters = {
allure: AllureReporter,
dot: DotReporter,
line: LineReporter,
list: ListReporter,
Expand Down

0 comments on commit 372cbf5

Please sign in to comment.