Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Show display name in the test report #481

Merged
merged 1 commit into from
Nov 30, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions resources/templates/report.pug
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,22 @@ html(lang="en")
ul.nav.nav-pills.mt-3(role='tablist')
li.nav-item
button.btn.btn-sm.btn-info.active(id='all-tab', data-toggle='pill', href='#all', role='tab', aria-controls='all') All
span.badge.badge-light.ml-2 #{passedTests.length+failedTests.length+skippedCount}
if failedTests.length
span.badge.badge-light.ml-2 #{allCount}
if failedCount
li.nav-item
button.btn.btn-sm.btn-danger.ml-3(id='fail-tab', data-toggle='pill', href='#fail', role='tab', aria-controls='fail') Failed
span.badge.badge-light.ml-2 #{failedTests.length}
if passedTests.length
span.badge.badge-light.ml-2 #{failedCount}
if passedCount
li.nav-item
button.btn.btn-sm.btn-success.ml-3(id='pass-tab', data-toggle='pill', href='#pass', role='tab', aria-controls='pass') Passed
span.badge.badge-light.ml-2 #{passedTests.length}
span.badge.badge-light.ml-2 #{passedCount}

div.tab-content.mt-3
div.tab-pane.fade.show.active(id='all', role='tabpanel', aria-labelledby='all-tab')
+collapseMethodTable(tests, 'detail-all')
if failedTests.length
if failedCount
div.tab-pane.fade(id='fail', role='tabpanel', aria-labelledby='fail-tab')
+collapseMethodTable(failedTests, 'detail-fail')
if passedTests.length
if passedCount
div.tab-pane.fade(id='pass', role='tabpanel', aria-labelledby='pass-tab')
+collapseMethodTable(passedTests, 'detail-pass')
68 changes: 34 additions & 34 deletions resources/templates/report_method_table.pug
Original file line number Diff line number Diff line change
@@ -1,39 +1,39 @@
mixin collapseMethodTable(children, tableName)
table.table
thead
tr
th(scope="col") Method
th(scope="col") Status
th(scope="col") Duration
tbody
- var index = 0
each child in children
- index++
tr.accordion-toggle(data-toggle="collapse", data-target=`#${tableName}${index}`, style="cursor:pointer", title="View details")
td #{child.fullName.replace("#", ".")}
td
if !child.result
mixin collapseMethodTable(children, type)
- var classIdx = 0
//- See https://github.com/pugjs/pug/issues/2559#issuecomment-289873794 for iterating a map in Pug
each entry in [...children]
- classIdx++
div.mt-1.table(style="padding:0.6rem")
div.row
div.col
h4 #{entry[0]}
- var methodIdx = 0
each method in entry[1]
- methodIdx++
div.row.accordion-toggle(data-toggle="collapse", data-target=`#${type}-${classIdx}-${methodIdx}`, style="cursor:pointer", title="View details")
div.cell.col-md-9 #{method.displayName}
div.cell.col-md-1
if !method.result
span.badge.badge-warning Not run
else if child.result.status === 'Pass'
else if method.result.status === 'Pass'
span.badge.badge-success Passed
else if child.result.status === 'Fail'
else if method.result.status === 'Fail'
span.badge.badge-danger Failed
else
span.badge.badge-secondary Skipped
td #{child.result && child.result.duration ? child.result.duration + "ms" : "N/A"}
tr.accordion-body(id=`${tableName}${index}`, class="collapse")
td(colspan="3")
table.table-sm
tbody
tr
th(scope="col") Message:
tr
td #{child.result && child.result.message ? child.result.message : "N/A"}
tr
th(scope="col") Stack trace:
tr
td
if child.result && child.result.details
pre.text-light: code #{child.result.details}
else
span N/A
div.cell.col-md-2 #{method.result && method.result.duration ? method.result.duration + "ms" : "N/A"}
div.accordion-body(id=`${type}-${classIdx}-${methodIdx}`, class="collapse")
div.row
div.col
h6 Message:
div.row
div.cell.col #{method.result && method.result.message ? method.result.message : "N/A"}
div.row
div.col
h6 Stack trace:
div.row
div.cell.col
if method.result && method.result.details
pre.text-light: code #{method.result.details}
else
span N/A
2 changes: 2 additions & 0 deletions resources/templates/scss/report.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@ $table-color: var(--vscode-foreground);

$font-size-base: .85rem !default;

div.cell { padding-bottom:.6rem }

@import "../../../node_modules/bootstrap/scss/bootstrap";
2 changes: 1 addition & 1 deletion src/protocols.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
import { Range } from 'vscode';

export interface ITestItemBase {
displayName: string;
fullName: string;
uri: string;
}

export interface ITestItem extends ITestItemBase {
displayName: string;
range: Range;
children: ITestItem[];
kind: TestKind;
Expand Down
1 change: 1 addition & 0 deletions src/runners/baseRunner/BaseRunnerResultAnalyzer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export abstract class BaseRunnerResultAnalyzer {
}

return {
displayName: test.displayName,
fullName: test.fullName,
uri: Uri.parse(test.uri).toString(),
result: testResultDetails,
Expand Down
17 changes: 1 addition & 16 deletions src/runners/testngRunner/TestNGRunnerResultAnalyzer.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

import { Uri } from 'vscode';
import { ITestItem } from '../../protocols';
import { BaseRunnerResultAnalyzer } from '../baseRunner/BaseRunnerResultAnalyzer';
import { ITestResult, ITestResultDetails, TestStatus } from '../models';
import { ITestResultDetails, TestStatus } from '../models';

const TEST_START: string = 'testStarted';
const TEST_FAIL: string = 'testFailed';
Expand Down Expand Up @@ -41,19 +39,6 @@ export class TestNGRunnerResultAnalyzer extends BaseRunnerResultAnalyzer {
break;
}
}

protected processMethod(test: ITestItem): ITestResult {
let testResultDetails: ITestResultDetails | undefined = this.testResults.get(test.fullName);
if (!testResultDetails) {
testResultDetails = { status: TestStatus.Skip };
}

return {
fullName: test.fullName,
uri: Uri.parse(test.uri).toString(),
result: testResultDetails,
};
}
}

interface ITestNGOutputData {
Expand Down
56 changes: 45 additions & 11 deletions src/testReportProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import * as path from 'path';
import * as pug from 'pug';
import { Disposable, ExtensionContext, Uri, WebviewPanel, window } from 'vscode';
import { ITestItemBase } from './protocols';
import { ITestResult, ITestResultDetails, TestStatus } from './runners/models';
import { ITestResultDetails, TestStatus } from './runners/models';
import { testResultManager } from './testResultManager';
import { getReportPosition } from './utils/testReportUtils';

Expand Down Expand Up @@ -46,24 +46,43 @@ class TestReportProvider implements Disposable {
}

public async provideHtmlContent(tests: ITestItemBase[]): Promise<string> {
const results: ITestResult[] = [];
const allResultsMap: Map<string, IReportMethod[]> = new Map();
const passedResultMap: Map<string, IReportMethod[]> = new Map();
const failedResultMap: Map<string, IReportMethod[]> = new Map();
let allCount: number = 0;
let passedCount: number = 0;
let failedCount: number = 0;
let skippedCount: number = 0;
for (const test of tests) {
const result: ITestResultDetails | undefined = testResultManager.getResult(Uri.parse(test.uri).fsPath, test.fullName);
allCount++;
if (result) {
results.push({uri: test.uri, fullName: test.fullName, result});
this.putMethodResultIntoMap(allResultsMap, test, result);
switch (result.status) {
case TestStatus.Pass:
this.putMethodResultIntoMap(passedResultMap, test, result);
passedCount++;
break;
case TestStatus.Fail:
this.putMethodResultIntoMap(failedResultMap, test, result);
failedCount++;
break;
case TestStatus.Skip:
skippedCount++;
break;
}
}
}

const passedTests: ITestItemBase[] = results.filter((result: ITestResult) => result.result && result.result.status === TestStatus.Pass);
const failedTests: ITestItemBase[] = results.filter((result: ITestResult) => result.result && result.result.status === TestStatus.Fail);
const skippedTests: ITestItemBase[] = results.filter((result: ITestResult) => result.result && result.result.status === TestStatus.Skip);

return this.compiledReportTemplate({
tests: results,
passedTests,
failedTests,
tests: allResultsMap,
passedTests: passedResultMap,
failedTests: failedResultMap,
allCount,
passedCount,
failedCount,
skippedCount,
cssFile: this.cssFileUri,
skippedCount: skippedTests.length,
});
}

Expand All @@ -73,10 +92,25 @@ class TestReportProvider implements Disposable {
}
}

private putMethodResultIntoMap(map: Map<string, IReportMethod[]>, test: ITestItemBase, result: ITestResultDetails): void {
const classFullName: string = test.fullName.substr(0, test.fullName.indexOf('#'));
const methods: IReportMethod[] | undefined = map.get(classFullName);
if (methods) {
methods.push({displayName: test.displayName, result});
} else {
map.set(classFullName, [{displayName: test.displayName, result}]);
}
}

private get cssFileUri(): string {
const cssFilePath: string = this.context.asAbsolutePath(path.join('resources', 'templates', 'css', 'report.css'));
return Uri.file(cssFilePath).with({ scheme: 'vscode-resource' }).toString();
}
}

interface IReportMethod {
displayName: string;
result: ITestResultDetails;
}

export const testReportProvider: TestReportProvider = new TestReportProvider();