From 25c36f6b3d56bd69cc31ad21b675ec1b157d55f7 Mon Sep 17 00:00:00 2001 From: Boris Serdiuk Date: Fri, 23 Aug 2019 13:17:01 -0700 Subject: [PATCH 1/3] update tsconfig to not transpile too much the oldest supported node 8 has native support for es2017 features, no need to transpile --- tsconfig.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tsconfig.json b/tsconfig.json index 39a3d6479..6bb16d97a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,7 @@ { "compilerOptions": { - "target": "es6", - "lib": ["es6"], + "target": "es2017", + "lib": ["es2017"], "module": "commonjs", "moduleResolution": "node", "declaration": true, From 9aaa78faa7faf448b3fe0ceb3930e7da7a14888f Mon Sep 17 00:00:00 2001 From: Boris Serdiuk Date: Fri, 23 Aug 2019 13:28:04 -0700 Subject: [PATCH 2/3] refactor labels retrieval in tests --- packages/allure-mocha/test/specs/feature.ts | 4 ++-- packages/allure-mocha/test/specs/owner.ts | 4 ++-- packages/allure-mocha/test/specs/severity.ts | 4 ++-- packages/allure-mocha/test/specs/story.ts | 4 ++-- packages/allure-mocha/test/specs/tag.ts | 4 ++-- packages/allure-mocha/test/utils/index.ts | 5 +++-- 6 files changed, 13 insertions(+), 12 deletions(-) diff --git a/packages/allure-mocha/test/specs/feature.ts b/packages/allure-mocha/test/specs/feature.ts index 20d788125..0d2b2a57b 100644 --- a/packages/allure-mocha/test/specs/feature.ts +++ b/packages/allure-mocha/test/specs/feature.ts @@ -1,7 +1,7 @@ import { Status } from "allure-js-commons"; import { expect } from "chai"; import { suite } from "mocha-typescript"; -import { findLabel, runTests } from "../utils"; +import { findLabelValue, runTests } from "../utils"; @suite class FeatureSuite { @@ -11,6 +11,6 @@ class FeatureSuite { const test = writerStub.getTestByName("shouldAssignFeature"); expect(test.status).eq(Status.PASSED); - expect(findLabel(test, "feature")!.value).eq("Login"); + expect(findLabelValue(test, "feature")).eq("Login"); } } diff --git a/packages/allure-mocha/test/specs/owner.ts b/packages/allure-mocha/test/specs/owner.ts index 1017635bd..dd680f1d5 100644 --- a/packages/allure-mocha/test/specs/owner.ts +++ b/packages/allure-mocha/test/specs/owner.ts @@ -1,7 +1,7 @@ import { Status } from "allure-js-commons"; import { expect } from "chai"; import { suite } from "mocha-typescript"; -import { findLabel, runTests } from "../utils"; +import { findLabelValue, runTests } from "../utils"; @suite class OwnerSuite { @@ -11,6 +11,6 @@ class OwnerSuite { const test = writerStub.getTestByName("shouldAssignOwner"); expect(test.status).eq(Status.PASSED); - expect(findLabel(test, "owner")!.value).eq("sskorol"); + expect(findLabelValue(test, "owner")).eq("sskorol"); } } diff --git a/packages/allure-mocha/test/specs/severity.ts b/packages/allure-mocha/test/specs/severity.ts index e084505d8..e12a075b8 100644 --- a/packages/allure-mocha/test/specs/severity.ts +++ b/packages/allure-mocha/test/specs/severity.ts @@ -1,7 +1,7 @@ import { Severity, Status } from "allure-js-commons"; import { expect } from "chai"; import { suite } from "mocha-typescript"; -import { findLabel, runTests } from "../utils"; +import { findLabelValue, runTests } from "../utils"; @suite class SeveritySuite { @@ -10,6 +10,6 @@ class SeveritySuite { const writerStub = await runTests("severity"); const test = writerStub.getTestByName("shouldAssignSeverity"); expect(test.status).eq(Status.PASSED); - expect(findLabel(test, "severity")!.value).eq(Severity.BLOCKER); + expect(findLabelValue(test, "severity")).eq(Severity.BLOCKER); } } diff --git a/packages/allure-mocha/test/specs/story.ts b/packages/allure-mocha/test/specs/story.ts index 4fd516f41..579cdbc06 100644 --- a/packages/allure-mocha/test/specs/story.ts +++ b/packages/allure-mocha/test/specs/story.ts @@ -1,7 +1,7 @@ import { Severity, Status } from "allure-js-commons"; import { expect } from "chai"; import { suite } from "mocha-typescript"; -import { findLabel, runTests } from "../utils"; +import { findLabelValue, runTests } from "../utils"; @suite class StorySuite { @@ -11,6 +11,6 @@ class StorySuite { const test = writerStub.getTestByName("shouldAssignStory"); expect(test.status).eq(Status.PASSED); - expect(findLabel(test, "story")!.value).eq("Common story"); + expect(findLabelValue(test, "story")).eq("Common story"); } } diff --git a/packages/allure-mocha/test/specs/tag.ts b/packages/allure-mocha/test/specs/tag.ts index 3c50c1585..60c56a614 100644 --- a/packages/allure-mocha/test/specs/tag.ts +++ b/packages/allure-mocha/test/specs/tag.ts @@ -1,7 +1,7 @@ import { Status } from "allure-js-commons"; import { expect } from "chai"; import { suite } from "mocha-typescript"; -import { findLabel, runTests } from "../utils"; +import { findLabelValue, runTests } from "../utils"; @suite class TagSuite { @@ -11,6 +11,6 @@ class TagSuite { const test = writerStub.getTestByName("shouldAssignTag"); expect(test.status).eq(Status.PASSED); - expect(findLabel(test, "tag")!.value).eq("smoke"); + expect(findLabelValue(test, "tag")).eq("smoke"); } } diff --git a/packages/allure-mocha/test/utils/index.ts b/packages/allure-mocha/test/utils/index.ts index a955686f8..addd49237 100644 --- a/packages/allure-mocha/test/utils/index.ts +++ b/packages/allure-mocha/test/utils/index.ts @@ -16,8 +16,9 @@ export function runTests(...specs: string[]): Promise { }); } -export function findLabel(test: TestResult, labelName: string) { - return test.labels.find(label => label.name === labelName); +export function findLabelValue(test: TestResult, labelName: string) { + const label = test.labels.find(label => label.name === labelName); + return label && label.value; } export function findParameter(test: TestResult, parameterName: string): any { From 2500ccf11007699d86051a11ae1c479c54dd8e20 Mon Sep 17 00:00:00 2001 From: Boris Serdiuk Date: Fri, 23 Aug 2019 13:28:40 -0700 Subject: [PATCH 3/3] Report parent suites with nesting correctly closes #38 --- packages/allure-mocha/src/AllureReporter.ts | 62 ++++++++++--------- .../allure-mocha/src/MochaAllureReporter.ts | 4 +- .../test/fixtures/specs/nested.ts | 25 ++++++++ .../test/fixtures/specs/pending.ts | 7 +++ packages/allure-mocha/test/specs/common.ts | 19 +++++- packages/allure-mocha/test/specs/nesting.ts | 45 ++++++++++++++ packages/allure-mocha/test/utils/index.ts | 7 ++- 7 files changed, 135 insertions(+), 34 deletions(-) create mode 100644 packages/allure-mocha/test/fixtures/specs/nested.ts create mode 100644 packages/allure-mocha/test/fixtures/specs/pending.ts create mode 100644 packages/allure-mocha/test/specs/nesting.ts diff --git a/packages/allure-mocha/src/AllureReporter.ts b/packages/allure-mocha/src/AllureReporter.ts index 57f4386db..f0e94f3a0 100644 --- a/packages/allure-mocha/src/AllureReporter.ts +++ b/packages/allure-mocha/src/AllureReporter.ts @@ -6,7 +6,8 @@ import { ContentType, LabelName, Stage, - Status + Status, + StatusDetails } from "allure-js-commons"; import { createHash } from "crypto"; import { MochaAllureInterface } from "./MochaAllureInterface"; @@ -45,11 +46,9 @@ export class AllureReporter { } public startSuite(suiteName: string) { - if (suiteName) { - const scope = this.currentSuite || this.runtime; - const suite = scope.startGroup(suiteName); - this.pushSuite(suite); - } + const scope = this.currentSuite || this.runtime; + const suite = scope.startGroup(suiteName || "Global"); + this.pushSuite(suite); } public endSuite() { @@ -62,39 +61,50 @@ export class AllureReporter { } } - public startCase(suiteName: string, testName: string) { + public startCase(test: Mocha.Test) { if (this.currentSuite === null) { throw new Error("No active suite"); } - this.currentTest = this.currentSuite.startTest(testName); - this.currentTest.fullName = testName; + this.currentTest = this.currentSuite.startTest(test.title); + this.currentTest.fullName = test.name; this.currentTest.historyId = createHash("md5") - .update(JSON.stringify({ suite: suiteName, test: testName })) + .update(test.fullTitle()) .digest("hex"); this.currentTest.stage = Stage.RUNNING; - this.currentTest.addLabel(LabelName.SUITE, this.currentSuite.name); + + if (test.parent) { + const [parentSuite, suite, ...subSuites] = test.parent.titlePath(); + if (parentSuite) { + this.currentTest.addLabel(LabelName.PARENT_SUITE, parentSuite); + } + if (suite) { + this.currentTest.addLabel(LabelName.SUITE, suite); + } + if (subSuites.length > 0) { + this.currentTest.addLabel(LabelName.SUB_SUITE, subSuites.join(" > ")); + } + } } public passTestCase() { - this.endTest(); + this.endTest(Status.PASSED); } public pendingTestCase(test: Mocha.Test) { - if (this.currentTest === null && this.currentSuite !== null) { - this.currentTest = this.currentSuite.startTest(test.title); - this.currentTest.statusDetails = { message: "Test ignored" }; + if (this.currentTest === null) { + this.startCase(test); } - - this.endTest(undefined, Status.SKIPPED); + this.endTest(Status.SKIPPED, { message: "Test ignored" }); } public failTestCase(test: Mocha.Test, error: Error) { - if (this.currentTest === null && this.currentSuite !== null) { - this.currentTest = this.currentSuite.startTest(test.fullTitle()); + if (this.currentTest === null) { + this.startCase(test); } + const status = error.name === "AssertionError" ? Status.FAILED : Status.BROKEN; - this.endTest(error); + this.endTest(status, { message: error.message, trace: error.stack }); } public writeAttachment(content: Buffer | string, type: ContentType): string { @@ -117,19 +127,15 @@ export class AllureReporter { this.suites.pop(); } - private endTest(error?: Error, status?: Status): void { + private endTest(status: Status, details?: StatusDetails): void { if (this.currentTest === null) { throw new Error("endTest while no test is running"); } - if (error) { - this.currentTest.statusDetails = { message: error.message, trace: error.stack }; + if (details) { + this.currentTest.statusDetails = details; } - - let errorStatus = Status.PASSED; - if (error) errorStatus = error.name === "AssertionError" ? Status.FAILED : Status.BROKEN; - - this.currentTest.status = status || errorStatus; + this.currentTest.status = status; this.currentTest.stage = Stage.FINISHED; this.currentTest.endTest(); this.currentTest = null; diff --git a/packages/allure-mocha/src/MochaAllureReporter.ts b/packages/allure-mocha/src/MochaAllureReporter.ts index 41b6ebe2d..b805636bf 100644 --- a/packages/allure-mocha/src/MochaAllureReporter.ts +++ b/packages/allure-mocha/src/MochaAllureReporter.ts @@ -32,8 +32,7 @@ export class MochaAllureReporter extends Mocha.reporters.Base { } private onTest(test: Mocha.Test) { - const suite = test.parent; - this.allure.startCase((suite && suite.title) || "Unnamed", test.title); + this.allure.startCase(test); } private onPassed(test: Mocha.Test) { @@ -41,7 +40,6 @@ export class MochaAllureReporter extends Mocha.reporters.Base { } private onFailed(test: Mocha.Test, error: Error) { - console.error(error); this.allure.failTestCase(test, error); } diff --git a/packages/allure-mocha/test/fixtures/specs/nested.ts b/packages/allure-mocha/test/fixtures/specs/nested.ts new file mode 100644 index 000000000..7fcb95a8f --- /dev/null +++ b/packages/allure-mocha/test/fixtures/specs/nested.ts @@ -0,0 +1,25 @@ +import { expect } from "chai"; + +it("top-level test", () => { + expect(1).to.be.eq(1); +}); + +describe("Parent suite", () => { + it("shallow test", () => { + expect(1).to.be.eq(1); + }); + + describe("Nested suite", () => { + describe("Sub suite", () => { + it("child test", () => { + expect(1).to.be.eq(1); + }); + + describe("Incredibly nested suite", () => { + it("the deepest test", () => { + expect(1).to.be.eq(1); + }); + }); + }); + }); +}); diff --git a/packages/allure-mocha/test/fixtures/specs/pending.ts b/packages/allure-mocha/test/fixtures/specs/pending.ts new file mode 100644 index 000000000..4ee33c6da --- /dev/null +++ b/packages/allure-mocha/test/fixtures/specs/pending.ts @@ -0,0 +1,7 @@ +describe("Pending tests", () => { + xit("simple pending", () => {}); + + it("skipped in runtime", function() { + this.skip(); + }); +}); diff --git a/packages/allure-mocha/test/specs/common.ts b/packages/allure-mocha/test/specs/common.ts index 2b3b1e58f..664e0891a 100644 --- a/packages/allure-mocha/test/specs/common.ts +++ b/packages/allure-mocha/test/specs/common.ts @@ -1,7 +1,7 @@ -import { Status } from "allure-js-commons"; +import { LabelName, Status } from "allure-js-commons"; import { expect } from "chai"; import { suite } from "mocha-typescript"; -import { runTests } from "../utils"; +import { findLabelValue, runTests } from "../utils"; @suite class CommonSuite { @@ -21,4 +21,19 @@ class CommonSuite { expect(skippedTest.statusDetails.message).eq("Test ignored"); expect(skippedTest.statusDetails.trace).eq(undefined); } + + @test + async shouldHaveCorrectSuitesForPendingTests() { + const writerStub = await runTests("pending"); + + const simplePending = writerStub.getTestByName("simple pending"); + expect(simplePending.status).eq(Status.SKIPPED); + expect(simplePending.historyId).eq("a50daf11cd50a0dcb2583dfaa90f796a"); + expect(findLabelValue(simplePending, LabelName.PARENT_SUITE)).eq("Pending tests"); + + const skippedInRuntime = writerStub.getTestByName("skipped in runtime"); + expect(skippedInRuntime.status).eq(Status.SKIPPED); + expect(skippedInRuntime.historyId).eq("e67a7b309c00b0cfa384a68790ef7f57"); + expect(findLabelValue(skippedInRuntime, LabelName.PARENT_SUITE)).eq("Pending tests"); + } } diff --git a/packages/allure-mocha/test/specs/nesting.ts b/packages/allure-mocha/test/specs/nesting.ts new file mode 100644 index 000000000..ac1a87647 --- /dev/null +++ b/packages/allure-mocha/test/specs/nesting.ts @@ -0,0 +1,45 @@ +import { InMemoryAllureWriter, LabelName } from "allure-js-commons"; +import { expect } from "chai"; +import { suite } from "mocha-typescript"; +import { findLabelValue, runTests } from "../utils"; + +@suite +class NestingSupport { + private writerStub!: InMemoryAllureWriter; + + async before() { + this.writerStub = await runTests("nested"); + } + + @test + shouldAssignAllSuites() { + const test = this.writerStub.getTestByName("child test"); + expect(findLabelValue(test, LabelName.PARENT_SUITE)).eq("Parent suite"); + expect(findLabelValue(test, LabelName.SUITE)).eq("Nested suite"); + expect(findLabelValue(test, LabelName.SUB_SUITE)).eq("Sub suite"); + } + + @test + shouldSkipMissingLevels() { + const test = this.writerStub.getTestByName("shallow test"); + expect(findLabelValue(test, LabelName.PARENT_SUITE)).eq("Parent suite"); + expect(findLabelValue(test, LabelName.SUITE)).eq(undefined); + expect(findLabelValue(test, LabelName.SUB_SUITE)).eq(undefined); + } + + @test + shouldHandleTopLevelTests() { + const test = this.writerStub.getTestByName("top-level test"); + expect(findLabelValue(test, LabelName.PARENT_SUITE)).eq(undefined); + expect(findLabelValue(test, LabelName.SUITE)).eq(undefined); + expect(findLabelValue(test, LabelName.SUB_SUITE)).eq(undefined); + } + + @test + shouldMergeSubSuiteNames() { + const test = this.writerStub.getTestByName("the deepest test"); + expect(findLabelValue(test, LabelName.PARENT_SUITE)).eq("Parent suite"); + expect(findLabelValue(test, LabelName.SUITE)).eq("Nested suite"); + expect(findLabelValue(test, LabelName.SUB_SUITE)).eq("Sub suite > Incredibly nested suite"); + } +} diff --git a/packages/allure-mocha/test/utils/index.ts b/packages/allure-mocha/test/utils/index.ts index addd49237..ee6879f43 100644 --- a/packages/allure-mocha/test/utils/index.ts +++ b/packages/allure-mocha/test/utils/index.ts @@ -29,5 +29,10 @@ function assignSpecs(mocha: Mocha, specs: string[]) { jetpack .dir(testDir) .find({ matching: specs.map(spec => `${spec}.js`) }) - .forEach(file => mocha.addFile(path.join(testDir, file))); + .forEach(file => { + const testPath = path.resolve(testDir, file); + // remove the test from node_modules cache, so it can be executed again + delete require.cache[testPath]; + mocha.addFile(testPath); + }); }