From f694d51d4b23b163f7c8227bc611fe8f799f40bc Mon Sep 17 00:00:00 2001 From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com> Date: Fri, 1 Nov 2024 04:19:28 +0700 Subject: [PATCH 1/6] test(codeceptjs): add std in/err to report; add extra args support --- .../test/spec/labels.test.ts | 9 ++--- .../test/spec/testplan.test.ts | 2 +- packages/allure-codeceptjs/test/utils.ts | 34 ++++++++++++++----- 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/packages/allure-codeceptjs/test/spec/labels.test.ts b/packages/allure-codeceptjs/test/spec/labels.test.ts index 2bd0047c4..236cb10dd 100644 --- a/packages/allure-codeceptjs/test/spec/labels.test.ts +++ b/packages/allure-codeceptjs/test/spec/labels.test.ts @@ -102,8 +102,7 @@ it("should not depend on CWD", async () => { }); `, }, - {}, - "nested", + { cwd: "nested" }, ); expect(tests).toEqual( @@ -141,8 +140,10 @@ it("should add labels from env variables", async () => { `, }, { - ALLURE_LABEL_A: "a", - ALLURE_LABEL_B: "b", + env: { + ALLURE_LABEL_A: "a", + ALLURE_LABEL_B: "b", + }, }, ); diff --git a/packages/allure-codeceptjs/test/spec/testplan.test.ts b/packages/allure-codeceptjs/test/spec/testplan.test.ts index 11bf1df96..5263e92d0 100644 --- a/packages/allure-codeceptjs/test/spec/testplan.test.ts +++ b/packages/allure-codeceptjs/test/spec/testplan.test.ts @@ -37,7 +37,7 @@ it("should support test plan", async () => { [testPlanFilename]: `${JSON.stringify(exampleTestPlan)}`, }, { - ALLURE_TESTPLAN_PATH: `./${testPlanFilename}`, + env: { ALLURE_TESTPLAN_PATH: `./${testPlanFilename}` }, }, ); diff --git a/packages/allure-codeceptjs/test/utils.ts b/packages/allure-codeceptjs/test/utils.ts index 0460baf89..eb5a17c49 100644 --- a/packages/allure-codeceptjs/test/utils.ts +++ b/packages/allure-codeceptjs/test/utils.ts @@ -7,11 +7,21 @@ import { attachment, step } from "allure-js-commons"; import type { AllureResults } from "allure-js-commons/sdk"; import { MessageReader } from "allure-js-commons/sdk/reporter"; +type RunOptions = { + env?: Record; + cwd?: string; + args?: string[]; +}; + +type RunResult = AllureResults & { + stdout: string[]; + stderr: string[]; +}; + export const runCodeceptJsInlineTest = async ( files: Record, - env?: Record, - cwd?: string, -): Promise => { + { env, cwd, args: extraCliArgs = [] }: RunOptions = {}, +): Promise => { const testFiles = { // package.json is used to find project root in case of absolute file paths are used // eslint-disable-next-line @stylistic/quotes @@ -40,7 +50,7 @@ export const runCodeceptJsInlineTest = async ( const modulePath = await step("resolve codeceptjs", () => { return require.resolve("codeceptjs/bin/codecept.js"); }); - const args = ["run", "-c", testDir]; + const args = ["run", "-c", testDir, ...extraCliArgs]; const testProcess = await step(`${modulePath} ${args.join(" ")}`, () => { return fork(modulePath, args, { env: { @@ -53,23 +63,31 @@ export const runCodeceptJsInlineTest = async ( }); }); + const stdout: string[] = []; + const stderr: string[] = []; + testProcess.stdout?.setEncoding("utf8").on("data", (chunk) => { - process.stdout.write(String(chunk)); + stdout.push(String(chunk)); }); testProcess.stderr?.setEncoding("utf8").on("data", (chunk) => { - process.stderr.write(String(chunk)); + stderr.push(String(chunk)); }); const messageReader = new MessageReader(); - // eslint-disable-next-line @typescript-eslint/no-unsafe-argument testProcess.on("message", messageReader.handleMessage); return new Promise((resolve) => { testProcess.on("exit", async () => { await messageReader.attachResults(); + if (stdout.length) { + await attachment("stdout", stdout.join("\n"), { contentType: "text/plain" }); + } + if (stderr.length) { + await attachment("stderr", stderr.join("\n"), { contentType: "text/plain" }); + } await rm(testDir, { recursive: true }); - return resolve(messageReader.results); + return resolve({ ...messageReader.results, stdout, stderr }); }); }); }; From 1008f5ea83cca973d60da8a1cf4bd94e77e93156 Mon Sep 17 00:00:00 2001 From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com> Date: Fri, 1 Nov 2024 04:29:10 +0700 Subject: [PATCH 2/6] feat(codeceptjs): add compatibility with mocha reporters --- packages/allure-codeceptjs/src/index.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/allure-codeceptjs/src/index.ts b/packages/allure-codeceptjs/src/index.ts index 1d8ac1bb2..83daf251f 100644 --- a/packages/allure-codeceptjs/src/index.ts +++ b/packages/allure-codeceptjs/src/index.ts @@ -6,7 +6,16 @@ import { AllureCodeceptJsReporter } from "./reporter.js"; const allurePlugin = (config: ReporterConfig) => { const mocha = container.mocha(); - mocha.reporter(AllureCodeceptJsReporter.prototype.constructor, { ...config }); + + // At this point the configured reporter's constructor has been initialized and is available via the _reporter field. + // See https://github.com/mochajs/mocha/blob/05097db4f2e0118f033978b8503aec36b1867c55/lib/mocha.js#L352 + // The field is not public but there is no other option to get the constructor; this is covered by tests in reporters.test.ts. + // eslint-disable-next-line no-underscore-dangle + const currentReporter = mocha._reporter; + mocha.reporter(AllureCodeceptJsReporter.prototype.constructor, { + ...config, + ...(currentReporter ? { extraReporters: [currentReporter, mocha.options.reporterOptions] } : {}), + }); return { ...allureCodeceptJsLegacyApi, From 84345a2bf68bff6c2736b4b56bc40442053f5482 Mon Sep 17 00:00:00 2001 From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com> Date: Fri, 1 Nov 2024 04:39:16 +0700 Subject: [PATCH 3/6] test(codeceptjs): cover mocha reporter support with tests --- .../test/spec/reporters.test.ts | 129 ++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 packages/allure-codeceptjs/test/spec/reporters.test.ts diff --git a/packages/allure-codeceptjs/test/spec/reporters.test.ts b/packages/allure-codeceptjs/test/spec/reporters.test.ts new file mode 100644 index 000000000..e8f84b636 --- /dev/null +++ b/packages/allure-codeceptjs/test/spec/reporters.test.ts @@ -0,0 +1,129 @@ +import { describe, expect, it } from "vitest"; +import { runCodeceptJsInlineTest } from "../utils.js"; + +describe("mocha reporters", () => { + it("cli should be enabled by default", async () => { + const { tests, stdout } = await runCodeceptJsInlineTest({ + "foo.test.js": ` + Feature("foo") + Scenario('bar', () => {}); + `, + }); + + expect(tests).toEqual([expect.objectContaining({ name: "bar" })]); + expect(stdout.join("").split("\n")).toEqual(expect.arrayContaining([expect.stringMatching(/^foo --/)])); + }); + + it("should support Mocha's built-in reporters", async () => { + const { tests, stdout } = await runCodeceptJsInlineTest({ + "foo.test.js": ` + Feature("foo") + Scenario('bar', () => {}); + `, + "codecept.conf.js": ` + const path = require("node:path"); + exports.config = { + tests: "./**/*.test.js", + output: path.resolve(__dirname, "./output"), + plugins: { + allure: { + require: require.resolve("allure-codeceptjs"), + enabled: true, + }, + }, + mocha: { + reporter: "json", + }, + }; + `, + }); + + const stdoutLines = stdout.join("").split("\n"); + + expect(tests).toEqual([expect.objectContaining({ name: "bar" })]); + const jsonString = stdoutLines.slice(stdoutLines.indexOf("{")).join(""); + expect(JSON.parse(jsonString)).toMatchObject({ + stats: expect.objectContaining({ + suites: 1, + tests: 1, + }), + }); + expect(stdoutLines).not.toEqual( + // no default cli reporter + expect.arrayContaining([expect.stringMatching(/^foo --/)]), + ); + }); + + it("should support local reporters", async () => { + const { tests, stdout } = await runCodeceptJsInlineTest({ + "foo.test.js": ` + Feature("foo") + Scenario('bar', () => {}); + `, + "reporter.cjs": ` + module.exports = function (r, o) { + r.on("start", () => { + console.log(JSON.stringify(o.reporterOptions)); + }); + }; + `, + "codecept.conf.js": ` + const path = require("node:path"); + exports.config = { + tests: "./**/*.test.js", + output: path.resolve(__dirname, "./output"), + plugins: { + allure: { + require: require.resolve("allure-codeceptjs"), + enabled: true, + }, + }, + mocha: { + reporter: "reporter.cjs", + reporterOptions: { foo: "bar" }, + }, + }; + `, + }); + + const stdoutLines = stdout.join("").split("\n"); + + expect(tests).toEqual([expect.objectContaining({ name: "bar" })]); + expect(stdoutLines).toEqual(expect.arrayContaining([String.raw`{"foo":"bar"}`])); + }); + + it("should support reporter constructors", async () => { + const { tests, stdout } = await runCodeceptJsInlineTest({ + "foo.test.js": ` + Feature("foo") + Scenario('bar', () => {}); + `, + "codecept.conf.js": ` + const path = require("node:path"); + exports.config = { + tests: "./**/*.test.js", + output: path.resolve(__dirname, "./output"), + plugins: { + allure: { + require: require.resolve("allure-codeceptjs"), + enabled: true, + }, + }, + mocha: { + reporter: function (r, o) { + r.on("start", () => { + console.log(JSON.stringify(o.reporterOptions)); + }); + }, + reporterOptions: { foo: { bar: "baz" } }, + }, + }; + `, + }); + + const stdoutLines = stdout.join("").split("\n"); + + expect(tests).toEqual([expect.objectContaining({ name: "bar" })]); + expect(stdoutLines).toEqual(expect.arrayContaining([String.raw`{"foo":{"bar":"baz"}}`])); + }); + }); From b48d4288d47dfbecef738723738852b15f0a11b0 Mon Sep 17 00:00:00 2001 From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com> Date: Fri, 1 Nov 2024 04:40:07 +0700 Subject: [PATCH 4/6] test(codeceptjs): add a test for --steps --- .../test/spec/reporters.test.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/packages/allure-codeceptjs/test/spec/reporters.test.ts b/packages/allure-codeceptjs/test/spec/reporters.test.ts index e8f84b636..57f716a61 100644 --- a/packages/allure-codeceptjs/test/spec/reporters.test.ts +++ b/packages/allure-codeceptjs/test/spec/reporters.test.ts @@ -14,6 +14,23 @@ describe("mocha reporters", () => { expect(stdout.join("").split("\n")).toEqual(expect.arrayContaining([expect.stringMatching(/^foo --/)])); }); + it("cli --steps should work out-of-box", async () => { + const { tests, stdout } = await runCodeceptJsInlineTest( + { + "foo.test.js": ` + Feature("foo") + Scenario('bar', () => {}); + `, + }, + { args: ["--steps"] }, + ); + + expect(tests).toEqual([expect.objectContaining({ name: "bar" })]); + expect(stdout.join("").split("\n")).toEqual( + expect.arrayContaining([expect.stringMatching(/^foo --/), expect.stringMatching(/^ {2}bar/)]), + ); + }); + it("should support Mocha's built-in reporters", async () => { const { tests, stdout } = await runCodeceptJsInlineTest({ "foo.test.js": ` From 13d8d02e98c738667b105659861e6e143850001d Mon Sep 17 00:00:00 2001 From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com> Date: Fri, 1 Nov 2024 04:41:02 +0700 Subject: [PATCH 5/6] test(codeceptjs): add an issue link template --- packages/allure-codeceptjs/vitest.config.ts | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/packages/allure-codeceptjs/vitest.config.ts b/packages/allure-codeceptjs/vitest.config.ts index 4c2f78527..f836907e2 100644 --- a/packages/allure-codeceptjs/vitest.config.ts +++ b/packages/allure-codeceptjs/vitest.config.ts @@ -6,7 +6,21 @@ export default defineConfig({ fileParallelism: false, testTimeout: 5000, setupFiles: ["./vitest-setup.ts"], - reporters: ["default", ["allure-vitest/reporter", { resultsDir: "./out/allure-results" }]], + reporters: [ + "default", + [ + "allure-vitest/reporter", + { + resultsDir: "./out/allure-results", + links: { + issue: { + urlTemplate: "https://github.com/allure-framework/allure-js/issues/%s", + nameTemplate: "Issue %s", + }, + }, + }, + ], + ], typecheck: { enabled: true, tsconfig: "./test/tsconfig.json", From 993eac184c204e73611a7031c4c21d6f622257ca Mon Sep 17 00:00:00 2001 From: Maksim Stepanov <17935127+delatrie@users.noreply.github.com> Date: Fri, 1 Nov 2024 04:41:49 +0700 Subject: [PATCH 6/6] test(codeceptjs): add link to issue 1167 --- packages/allure-codeceptjs/test/spec/reporters.test.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/allure-codeceptjs/test/spec/reporters.test.ts b/packages/allure-codeceptjs/test/spec/reporters.test.ts index 57f716a61..40f8ea218 100644 --- a/packages/allure-codeceptjs/test/spec/reporters.test.ts +++ b/packages/allure-codeceptjs/test/spec/reporters.test.ts @@ -1,4 +1,5 @@ import { describe, expect, it } from "vitest"; +import { issue } from "allure-js-commons"; import { runCodeceptJsInlineTest } from "../utils.js"; describe("mocha reporters", () => { @@ -15,6 +16,8 @@ describe("mocha reporters", () => { }); it("cli --steps should work out-of-box", async () => { + await issue("1167"); + const { tests, stdout } = await runCodeceptJsInlineTest( { "foo.test.js": ` @@ -143,4 +146,4 @@ describe("mocha reporters", () => { expect(tests).toEqual([expect.objectContaining({ name: "bar" })]); expect(stdoutLines).toEqual(expect.arrayContaining([String.raw`{"foo":{"bar":"baz"}}`])); }); - }); +});