allure 3.3.1 → 3.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -50,6 +50,12 @@ For example, if you're using `npm` as your test runner, the command would be:
50
50
  npx allure run -- npm test
51
51
  ```
52
52
 
53
+ To hide specific labels use `--hide-labels` option:
54
+
55
+ ```bash
56
+ npx allure run --hide-labels=owner --hide-labels=tag -- npm test
57
+ ```
58
+
53
59
  To successfully generate a report, ensure that your test setup outputs results into an `allure-results` directory, which is automatically detected by Allure 3. This directory can be placed at any nested level within your project (e.g., `out/tests/allure-results`), provided it retains the correct name.
54
60
 
55
61
  After the tests complete, the report is generated automatically. Existing results from previous runs are ignored, as Allure 3 focuses solely on new data to ensure accurate and up-to-date reporting.
@@ -121,6 +127,7 @@ import { defineConfig } from "allure";
121
127
  export default defineConfig({
122
128
  name: "Allure Report Example",
123
129
  output: "./out/allure-report",
130
+ hideLabels: ["owner", /^_/],
124
131
  plugins: {
125
132
  awesome: {
126
133
  options: {
@@ -140,6 +147,7 @@ The configuration file allows you to fine-tune report generation. Key options in
140
147
 
141
148
  - **`name`**: Specifies the report’s display name.
142
149
  - **`output`**: Defines the directory where the report will be saved.
150
+ - **`hideLabels`** *(`(string | RegExp)[]`)*: Hides matching labels by name in report data. Currently, only Allure Awesome report respects the option. Labels with names starting with `_` are hidden by default.
143
151
  - **`plugins`**: Enables and configures plugins, with each supporting various options.
144
152
 
145
153
  ### Awesome Plugin Options
@@ -1,10 +1,10 @@
1
- import { AllureReport, readConfig } from "@allurereport/core";
2
- import Allure2Plugin from "@allurereport/plugin-allure2";
3
- import { Command, Option } from "clipanion";
4
1
  import * as console from "node:console";
5
2
  import { existsSync } from "node:fs";
6
3
  import { realpath } from "node:fs/promises";
7
4
  import process, { exit } from "node:process";
5
+ import { AllureReport, readConfig } from "@allurereport/core";
6
+ import Allure2Plugin from "@allurereport/plugin-allure2";
7
+ import { Command, Option } from "clipanion";
8
8
  import { red } from "yoctocolors";
9
9
  export class Allure2Command extends Command {
10
10
  constructor() {
@@ -14,5 +14,6 @@ export declare class AwesomeCommand extends Command {
14
14
  historyPath: string | undefined;
15
15
  knownIssues: string | undefined;
16
16
  groupBy: string | undefined;
17
+ hideLabels: string[] | undefined;
17
18
  execute(): Promise<void>;
18
19
  }
@@ -1,10 +1,10 @@
1
- import { AllureReport, readConfig } from "@allurereport/core";
2
- import { default as AwesomePlugin } from "@allurereport/plugin-awesome";
3
- import { Command, Option } from "clipanion";
4
1
  import * as console from "node:console";
5
2
  import { existsSync } from "node:fs";
6
3
  import { realpath } from "node:fs/promises";
7
4
  import process, { exit } from "node:process";
5
+ import { AllureReport, readConfig } from "@allurereport/core";
6
+ import { default as AwesomePlugin } from "@allurereport/plugin-awesome";
7
+ import { Command, Option } from "clipanion";
8
8
  import { red } from "yoctocolors";
9
9
  export class AwesomeCommand extends Command {
10
10
  constructor() {
@@ -43,6 +43,9 @@ export class AwesomeCommand extends Command {
43
43
  this.groupBy = Option.String("--group-by,-g", {
44
44
  description: "Group test results by labels. The labels should be separated by commas",
45
45
  });
46
+ this.hideLabels = Option.Array("--hide-labels", {
47
+ description: "Hide labels by exact name in generated reports. Repeat the option for multiple labels",
48
+ });
46
49
  }
47
50
  async execute() {
48
51
  if (!existsSync(this.resultsDir)) {
@@ -52,6 +55,14 @@ export class AwesomeCommand extends Command {
52
55
  }
53
56
  const cwd = await realpath(this.cwd ?? process.cwd());
54
57
  const before = new Date().getTime();
58
+ const hideLabels = this.hideLabels?.length ? this.hideLabels : undefined;
59
+ const config = await readConfig(cwd, this.config, {
60
+ output: this.output,
61
+ name: this.reportName,
62
+ knownIssuesPath: this.knownIssues,
63
+ historyPath: this.historyPath,
64
+ hideLabels,
65
+ });
55
66
  const defaultAwesomeOptions = {
56
67
  singleFile: this.singleFile ?? false,
57
68
  logo: this.logo,
@@ -59,12 +70,6 @@ export class AwesomeCommand extends Command {
59
70
  reportLanguage: this.reportLanguage,
60
71
  groupBy: this.groupBy?.split?.(",") ?? ["parentSuite", "suite", "subSuite"],
61
72
  };
62
- const config = await readConfig(cwd, this.config, {
63
- output: this.output,
64
- name: this.reportName,
65
- knownIssuesPath: this.knownIssues,
66
- historyPath: this.historyPath,
67
- });
68
73
  config.plugins = [
69
74
  {
70
75
  id: "awesome",
@@ -1,10 +1,10 @@
1
- import { AllureReport, readConfig } from "@allurereport/core";
2
- import ClassicPlugin from "@allurereport/plugin-classic";
3
- import { Command, Option } from "clipanion";
4
1
  import * as console from "node:console";
5
2
  import { existsSync } from "node:fs";
6
3
  import { realpath } from "node:fs/promises";
7
4
  import process, { exit } from "node:process";
5
+ import { AllureReport, readConfig } from "@allurereport/core";
6
+ import ClassicPlugin from "@allurereport/plugin-classic";
7
+ import { Command, Option } from "clipanion";
8
8
  import { red } from "yoctocolors";
9
9
  export class ClassicCommand extends Command {
10
10
  constructor() {
@@ -1,7 +1,7 @@
1
+ import { exit } from "node:process";
1
2
  import { AllureReport } from "@allurereport/core";
2
3
  import { KnownError } from "@allurereport/service";
3
4
  import { glob } from "glob";
4
- import { exit } from "node:process";
5
5
  import { red } from "yoctocolors";
6
6
  import { logError } from "../../utils/logs.js";
7
7
  export const generate = async (params) => {
@@ -1,11 +1,11 @@
1
- import { AllureReport, readConfig } from "@allurereport/core";
2
- import CsvPlugin from "@allurereport/plugin-csv";
3
- import { Command, Option } from "clipanion";
4
1
  import * as console from "node:console";
5
2
  import { existsSync } from "node:fs";
6
3
  import { realpath } from "node:fs/promises";
7
4
  import { isAbsolute, join } from "node:path";
8
5
  import process, { exit } from "node:process";
6
+ import { AllureReport, readConfig } from "@allurereport/core";
7
+ import CsvPlugin from "@allurereport/plugin-csv";
8
+ import { Command, Option } from "clipanion";
9
9
  import { red } from "yoctocolors";
10
10
  export class CsvCommand extends Command {
11
11
  constructor() {
@@ -1,10 +1,10 @@
1
- import { AllureReport, readConfig } from "@allurereport/core";
2
- import DashboardPlugin from "@allurereport/plugin-dashboard";
3
- import { Command, Option } from "clipanion";
4
1
  import * as console from "node:console";
5
2
  import { existsSync } from "node:fs";
6
3
  import { realpath } from "node:fs/promises";
7
4
  import process, { exit } from "node:process";
5
+ import { AllureReport, readConfig } from "@allurereport/core";
6
+ import DashboardPlugin from "@allurereport/plugin-dashboard";
7
+ import { Command, Option } from "clipanion";
8
8
  import { red } from "yoctocolors";
9
9
  export class DashboardCommand extends Command {
10
10
  constructor() {
@@ -11,5 +11,6 @@ export declare class GenerateCommand extends Command {
11
11
  open: boolean | undefined;
12
12
  port: string | undefined;
13
13
  historyLimit: string | undefined;
14
+ hideLabels: string[] | undefined;
14
15
  execute(): Promise<void>;
15
16
  }
@@ -1,7 +1,7 @@
1
+ import { cwd as processCwd } from "node:process";
1
2
  import { readConfig } from "@allurereport/core";
2
3
  import { serve } from "@allurereport/static-server";
3
4
  import { Command, Option } from "clipanion";
4
- import { cwd as processCwd } from "node:process";
5
5
  import { generate } from "./commons/generate.js";
6
6
  export class GenerateCommand extends Command {
7
7
  constructor() {
@@ -34,14 +34,19 @@ export class GenerateCommand extends Command {
34
34
  this.historyLimit = Option.String("--history-limit", {
35
35
  description: "Limits the number of history entries to keep (default: unlimited)",
36
36
  });
37
+ this.hideLabels = Option.Array("--hide-labels", {
38
+ description: "Hide labels by exact name in generated reports. Repeat the option for multiple labels",
39
+ });
37
40
  }
38
41
  async execute() {
39
42
  const cwd = this.cwd ?? processCwd();
43
+ const hideLabels = this.hideLabels?.length ? this.hideLabels : undefined;
40
44
  const config = await readConfig(cwd, this.config, {
41
45
  name: this.reportName,
42
46
  output: this.output,
43
47
  open: this.open,
44
48
  port: this.port,
49
+ hideLabels,
45
50
  historyLimit: this.historyLimit ? parseInt(this.historyLimit, 10) : undefined,
46
51
  });
47
52
  await generate({
@@ -1,8 +1,8 @@
1
- import { AllureReport, resolveConfig } from "@allurereport/core";
2
- import { Command, Option } from "clipanion";
3
1
  import * as console from "node:console";
4
2
  import { existsSync } from "node:fs";
5
3
  import { exit } from "node:process";
4
+ import { AllureReport, resolveConfig } from "@allurereport/core";
5
+ import { Command, Option } from "clipanion";
6
6
  import { red } from "yoctocolors";
7
7
  export class HistoryCommand extends Command {
8
8
  constructor() {
@@ -1,8 +1,8 @@
1
+ import { realpath } from "node:fs/promises";
2
+ import process, { exit } from "node:process";
1
3
  import { getPluginInstance, readConfig } from "@allurereport/core";
2
4
  import JiraPlugin from "@allurereport/plugin-jira";
3
5
  import { Command, Option, UsageError } from "clipanion";
4
- import { realpath } from "node:fs/promises";
5
- import process, { exit } from "node:process";
6
6
  import { green, red } from "yoctocolors";
7
7
  class BaseJiraCommand extends Command {
8
8
  constructor() {
@@ -1,9 +1,9 @@
1
- import { AllureReport, resolveConfig, writeKnownIssues } from "@allurereport/core";
2
- import { Command, Option } from "clipanion";
3
1
  import * as console from "node:console";
4
2
  import { existsSync } from "node:fs";
5
3
  import { resolve } from "node:path";
6
4
  import { exit } from "node:process";
5
+ import { AllureReport, resolveConfig, writeKnownIssues } from "@allurereport/core";
6
+ import { Command, Option } from "clipanion";
7
7
  import { red } from "yoctocolors";
8
8
  export class KnownIssueCommand extends Command {
9
9
  constructor() {
@@ -1,10 +1,10 @@
1
- import { AllureReport, readConfig } from "@allurereport/core";
2
- import LogPlugin from "@allurereport/plugin-log";
3
- import { Command, Option } from "clipanion";
4
1
  import * as console from "node:console";
5
2
  import { existsSync } from "node:fs";
6
3
  import { realpath } from "node:fs/promises";
7
4
  import process, { exit } from "node:process";
5
+ import { AllureReport, readConfig } from "@allurereport/core";
6
+ import LogPlugin from "@allurereport/plugin-log";
7
+ import { Command, Option } from "clipanion";
8
8
  import { red } from "yoctocolors";
9
9
  export class LogCommand extends Command {
10
10
  constructor() {
@@ -6,5 +6,6 @@ export declare class OpenCommand extends Command {
6
6
  config: string | undefined;
7
7
  port: string | undefined;
8
8
  cwd: string | undefined;
9
+ hideLabels: string[] | undefined;
9
10
  execute(): Promise<void>;
10
11
  }
@@ -1,12 +1,12 @@
1
- import { readConfig } from "@allurereport/core";
2
- import { serve } from "@allurereport/static-server";
3
- import { Command, Option } from "clipanion";
4
- import { glob } from "glob";
5
1
  import { existsSync } from "node:fs";
6
2
  import { mkdtemp, rm } from "node:fs/promises";
7
3
  import { tmpdir } from "node:os";
8
4
  import { join } from "node:path";
9
5
  import { cwd as processCwd } from "node:process";
6
+ import { readConfig } from "@allurereport/core";
7
+ import { serve } from "@allurereport/static-server";
8
+ import { Command, Option } from "clipanion";
9
+ import { glob } from "glob";
10
10
  import { generate } from "./commons/generate.js";
11
11
  export class OpenCommand extends Command {
12
12
  constructor() {
@@ -24,9 +24,13 @@ export class OpenCommand extends Command {
24
24
  this.cwd = Option.String("--cwd", {
25
25
  description: "The working directory for the command to run (default: current working directory)",
26
26
  });
27
+ this.hideLabels = Option.Array("--hide-labels", {
28
+ description: "Hide labels by exact name in generated reports. Repeat the option for multiple labels",
29
+ });
27
30
  }
28
31
  async execute() {
29
32
  const cwd = this.cwd ?? processCwd();
33
+ const hideLabels = this.hideLabels?.length ? this.hideLabels : undefined;
30
34
  const targetFullPath = join(cwd, this.resultsDir ?? "allure-report");
31
35
  const summaryFiles = existsSync(targetFullPath)
32
36
  ? await glob(join(targetFullPath, "**", "summary.json"), {
@@ -53,6 +57,7 @@ export class OpenCommand extends Command {
53
57
  const config = await readConfig(cwd, this.config, {
54
58
  port: this.port,
55
59
  output: tmpDir,
60
+ hideLabels,
56
61
  });
57
62
  await generate({
58
63
  resultsDir: targetFullPath,
@@ -10,6 +10,7 @@ export declare class QualityGateCommand extends Command {
10
10
  successRate: number | undefined;
11
11
  knownIssues: string | undefined;
12
12
  environment: string | undefined;
13
+ environmentName: string | undefined;
13
14
  cwd: string | undefined;
14
15
  execute(): Promise<void>;
15
16
  }
@@ -1,11 +1,12 @@
1
- import { AllureReport, QualityGateState, readConfig, stringifyQualityGateResults } from "@allurereport/core";
2
- import { Command, Option } from "clipanion";
3
- import { glob } from "glob";
4
1
  import * as console from "node:console";
5
2
  import { realpath } from "node:fs/promises";
6
3
  import { exit, cwd as processCwd } from "node:process";
4
+ import { AllureReport, QualityGateState, readConfig, stringifyQualityGateResults } from "@allurereport/core";
5
+ import { Command, Option } from "clipanion";
6
+ import { glob } from "glob";
7
7
  import * as typanion from "typanion";
8
8
  import { red } from "yoctocolors";
9
+ import { environmentNameOption, environmentOption, normalizeCommandEnvironmentOptions, resolveCommandEnvironment, } from "../utils/environment.js";
9
10
  export class QualityGateCommand extends Command {
10
11
  constructor() {
11
12
  super(...arguments);
@@ -34,20 +35,25 @@ export class QualityGateCommand extends Command {
34
35
  this.knownIssues = Option.String("--known-issues", {
35
36
  description: "Path to the known issues file. Updates the file and quarantines failed tests when specified",
36
37
  });
37
- this.environment = Option.String("--environment,--env", {
38
- description: "Force specific environment to all tests in the run. Given environment has higher priority than the one defined in the config file (default: empty string)",
39
- });
38
+ this.environment = environmentOption();
39
+ this.environmentName = environmentNameOption();
40
40
  this.cwd = Option.String("--cwd", {
41
41
  description: "The working directory for the command to run (default: current working directory)",
42
42
  });
43
43
  }
44
44
  async execute() {
45
+ const environmentOptions = {
46
+ environment: this.environment,
47
+ environmentName: this.environmentName,
48
+ };
49
+ normalizeCommandEnvironmentOptions(environmentOptions);
45
50
  const cwd = await realpath(this.cwd ?? processCwd());
46
51
  const resultsDir = (this.resultsDir ?? "./**/allure-results").replace(/[\\/]$/, "");
47
- const { maxFailures, minTestsCount, successRate, fastFail, knownIssues: knownIssuesPath, environment } = this;
52
+ const { maxFailures, minTestsCount, successRate, fastFail, knownIssues: knownIssuesPath } = this;
48
53
  const config = await readConfig(cwd, this.config, {
49
54
  knownIssuesPath,
50
55
  });
56
+ const resolvedEnvironment = resolveCommandEnvironment(config, environmentOptions);
51
57
  const rules = {};
52
58
  if (maxFailures !== undefined) {
53
59
  rules.maxFailures = maxFailures;
@@ -67,7 +73,10 @@ export class QualityGateCommand extends Command {
67
73
  rules: [rules],
68
74
  };
69
75
  }
70
- const allureReport = new AllureReport(config);
76
+ const allureReport = new AllureReport({
77
+ ...config,
78
+ environment: resolvedEnvironment?.id,
79
+ });
71
80
  if (!allureReport.hasQualityGate) {
72
81
  console.error(red("Quality gate is not configured!"));
73
82
  console.error(red("Add qualityGate to the config or consult help to know, how to use the command with command-line arguments"));
@@ -94,7 +103,7 @@ export class QualityGateCommand extends Command {
94
103
  const notHiddenTrs = trs.filter((tr) => !tr.hidden);
95
104
  const { results, fastFailed } = await allureReport.validate({
96
105
  trs: notHiddenTrs,
97
- environment,
106
+ environment: resolvedEnvironment?.id,
98
107
  knownIssues,
99
108
  state,
100
109
  });
@@ -113,7 +122,7 @@ export class QualityGateCommand extends Command {
113
122
  const validationResults = await allureReport.validate({
114
123
  trs: allTrs,
115
124
  knownIssues,
116
- environment,
125
+ environment: resolvedEnvironment?.id,
117
126
  });
118
127
  if (validationResults.results.length === 0) {
119
128
  exit(0);
@@ -4,14 +4,14 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
4
4
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
5
  };
6
6
  var _ResultsPackCommand_instances, _ResultsPackCommand_formatSize;
7
- import AdmZip from "adm-zip";
8
- import { Command, Option } from "clipanion";
9
- import { glob } from "glob";
10
7
  import * as console from "node:console";
11
8
  import * as fs from "node:fs/promises";
12
9
  import { realpath } from "node:fs/promises";
13
10
  import { basename, join, resolve } from "node:path";
14
11
  import { exit } from "node:process";
12
+ import AdmZip from "adm-zip";
13
+ import { Command, Option } from "clipanion";
14
+ import { glob } from "glob";
15
15
  import { green, red } from "yoctocolors";
16
16
  export class ResultsPackCommand extends Command {
17
17
  constructor() {
@@ -1,9 +1,9 @@
1
- import AdmZip from "adm-zip";
2
- import { Command, Option } from "clipanion";
3
1
  import * as console from "node:console";
4
2
  import * as fs from "node:fs/promises";
5
3
  import { realpath } from "node:fs/promises";
6
4
  import { basename, resolve } from "node:path";
5
+ import AdmZip from "adm-zip";
6
+ import { Command, Option } from "clipanion";
7
7
  import { green, red } from "yoctocolors";
8
8
  export class ResultsUnpackCommand extends Command {
9
9
  constructor() {
@@ -25,13 +25,15 @@ export class ResultsUnpackCommand extends Command {
25
25
  try {
26
26
  await fs.mkdir(outputDir, { recursive: true });
27
27
  }
28
- catch (ignored) { }
28
+ catch {
29
+ }
29
30
  let successCount = 0;
30
31
  let failCount = 0;
31
32
  for (const archivePath of archives) {
32
33
  const resolvedPath = resolve(cwd, archivePath);
33
34
  try {
34
- await fs.access(resolvedPath);
35
+ await fs.access(resolvedPath, fs.constants.R_OK);
36
+ await fs.access(outputDir, fs.constants.W_OK);
35
37
  console.log(`Extracting ${resolvedPath} to ${outputDir}`);
36
38
  try {
37
39
  const zip = new AdmZip(resolvedPath);
@@ -20,7 +20,9 @@ export declare class RunCommand extends Command {
20
20
  ignoreLogs: boolean | undefined;
21
21
  dump: string | undefined;
22
22
  environment: string | undefined;
23
+ environmentName: string | undefined;
23
24
  historyLimit: string | undefined;
25
+ hideLabels: string[] | undefined;
24
26
  commandToRun: string[];
25
27
  get logs(): "pipe" | "inherit" | "ignore";
26
28
  execute(): Promise<void>;
@@ -1,3 +1,9 @@
1
+ import * as console from "node:console";
2
+ import { randomUUID } from "node:crypto";
3
+ import { mkdtemp, realpath, rm, writeFile } from "node:fs/promises";
4
+ import { tmpdir } from "node:os";
5
+ import { join, resolve } from "node:path";
6
+ import process, { exit } from "node:process";
1
7
  import { AllureReport, QualityGateState, isFileNotFoundError, readConfig, stringifyQualityGateResults, } from "@allurereport/core";
2
8
  import { createTestPlan } from "@allurereport/core-api";
3
9
  import { allureResultsDirectoriesWatcher, delayedFileProcessingWatcher, newFilesInDirectoryWatcher, } from "@allurereport/directory-watcher";
@@ -5,14 +11,9 @@ import Awesome from "@allurereport/plugin-awesome";
5
11
  import { BufferResultFile, PathResultFile } from "@allurereport/reader-api";
6
12
  import { KnownError } from "@allurereport/service";
7
13
  import { serve } from "@allurereport/static-server";
8
- import { Command, Option } from "clipanion";
9
- import * as console from "node:console";
10
- import { randomUUID } from "node:crypto";
11
- import { mkdtemp, realpath, rm, writeFile } from "node:fs/promises";
12
- import { tmpdir } from "node:os";
13
- import { join, resolve } from "node:path";
14
- import process, { exit } from "node:process";
14
+ import { Command, Option, UsageError } from "clipanion";
15
15
  import { red } from "yoctocolors";
16
+ import { environmentNameOption, environmentOption, normalizeCommandEnvironmentOptions, resolveCommandEnvironment, } from "../utils/environment.js";
16
17
  import { logTests, runProcess, terminationOf } from "../utils/index.js";
17
18
  import { logError } from "../utils/logs.js";
18
19
  import { stopProcessTree } from "../utils/process.js";
@@ -163,12 +164,14 @@ export class RunCommand extends Command {
163
164
  this.dump = Option.String("--dump", {
164
165
  description: "Runs tests in dump mode to collect results to a dump archive with the provided name (default: empty string)",
165
166
  });
166
- this.environment = Option.String("--environment,--env", {
167
- description: "Force specific environment to all tests in the run. Given environment has higher priority than the one defined in the config file (default: empty string)",
168
- });
167
+ this.environment = environmentOption();
168
+ this.environmentName = environmentNameOption();
169
169
  this.historyLimit = Option.String("--history-limit", {
170
170
  description: "Limits the number of history entries to keep (default: unlimited)",
171
171
  });
172
+ this.hideLabels = Option.Array("--hide-labels", {
173
+ description: "Hide labels by exact name in generated reports. Repeat the option for multiple labels",
174
+ });
172
175
  this.commandToRun = Option.Rest();
173
176
  }
174
177
  get logs() {
@@ -180,8 +183,13 @@ export class RunCommand extends Command {
180
183
  async execute() {
181
184
  const args = this.commandToRun.filter((arg) => arg !== "--");
182
185
  if (!args || !args.length) {
183
- throw new Error("expecting command to be specified after --, e.g. allure run -- npm run test");
186
+ throw new UsageError("expecting command to be specified after --, e.g. allure run -- npm run test");
184
187
  }
188
+ const environmentOptions = {
189
+ environment: this.environment,
190
+ environmentName: this.environmentName,
191
+ };
192
+ normalizeCommandEnvironmentOptions(environmentOptions);
185
193
  const before = new Date().getTime();
186
194
  process.on("exit", (exitCode) => {
187
195
  const after = new Date().getTime();
@@ -190,6 +198,7 @@ export class RunCommand extends Command {
190
198
  const command = args[0];
191
199
  const commandArgs = args.slice(1);
192
200
  const cwd = await realpath(this.cwd ?? process.cwd());
201
+ const hideLabels = this.hideLabels?.length ? this.hideLabels : undefined;
193
202
  console.log(`${command} ${commandArgs.join(" ")}`);
194
203
  const maxRerun = this.rerun ? parseInt(this.rerun, 10) : 0;
195
204
  const config = await readConfig(cwd, this.config, {
@@ -197,8 +206,10 @@ export class RunCommand extends Command {
197
206
  name: this.reportName,
198
207
  open: this.open,
199
208
  port: this.port,
209
+ hideLabels,
200
210
  historyLimit: this.historyLimit ? parseInt(this.historyLimit, 10) : undefined,
201
211
  });
212
+ const resolvedEnvironment = resolveCommandEnvironment(config, environmentOptions);
202
213
  const withQualityGate = !!config.qualityGate;
203
214
  const withRerun = !!this.rerun;
204
215
  if (withQualityGate && withRerun) {
@@ -216,7 +227,7 @@ export class RunCommand extends Command {
216
227
  }
217
228
  const allureReport = new AllureReport({
218
229
  ...config,
219
- environment: this.environment,
230
+ environment: resolvedEnvironment?.id,
220
231
  dump: this.dump,
221
232
  realTime: false,
222
233
  plugins: [
@@ -251,7 +262,7 @@ export class RunCommand extends Command {
251
262
  cwd,
252
263
  command,
253
264
  commandArgs,
254
- environment: this.environment,
265
+ environment: resolvedEnvironment?.id,
255
266
  environmentVariables: {},
256
267
  withQualityGate,
257
268
  });
@@ -275,7 +286,7 @@ export class RunCommand extends Command {
275
286
  cwd,
276
287
  command,
277
288
  commandArgs,
278
- environment: this.environment,
289
+ environment: resolvedEnvironment?.id,
279
290
  environmentVariables: {
280
291
  ALLURE_TESTPLAN_PATH: testPlanPath,
281
292
  ALLURE_RERUN: `${rerun}`,
@@ -291,7 +302,7 @@ export class RunCommand extends Command {
291
302
  const { results } = await allureReport.validate({
292
303
  trs,
293
304
  knownIssues,
294
- environment: this.environment,
305
+ environment: resolvedEnvironment?.id,
295
306
  });
296
307
  qualityGateResults = results;
297
308
  }
@@ -1,10 +1,10 @@
1
- import { AllureReport, readConfig } from "@allurereport/core";
2
- import SlackPlugin from "@allurereport/plugin-slack";
3
- import { Command, Option } from "clipanion";
4
1
  import * as console from "node:console";
5
2
  import { existsSync } from "node:fs";
6
3
  import { realpath } from "node:fs/promises";
7
4
  import process, { exit } from "node:process";
5
+ import { AllureReport, readConfig } from "@allurereport/core";
6
+ import SlackPlugin from "@allurereport/plugin-slack";
7
+ import { Command, Option } from "clipanion";
8
8
  import { red } from "yoctocolors";
9
9
  export class SlackCommand extends Command {
10
10
  constructor() {
@@ -1,9 +1,9 @@
1
- import { AllureReport, resolveConfig } from "@allurereport/core";
2
- import { Command, Option } from "clipanion";
3
1
  import * as console from "node:console";
4
2
  import { existsSync } from "node:fs";
5
3
  import { basename, dirname, resolve } from "node:path";
6
4
  import { exit } from "node:process";
5
+ import { AllureReport, resolveConfig } from "@allurereport/core";
6
+ import { Command, Option } from "clipanion";
7
7
  import { red } from "yoctocolors";
8
8
  export class TestPlanCommand extends Command {
9
9
  constructor() {
@@ -1,3 +1,8 @@
1
+ import * as console from "node:console";
2
+ import { existsSync } from "node:fs";
3
+ import { rm } from "node:fs/promises";
4
+ import { join, resolve } from "node:path";
5
+ import process, { exit } from "node:process";
1
6
  import { AllureReport, isFileNotFoundError, readConfig } from "@allurereport/core";
2
7
  import { newFilesInDirectoryWatcher } from "@allurereport/directory-watcher";
3
8
  import Awesome from "@allurereport/plugin-awesome";
@@ -6,11 +11,6 @@ import ServerReloadPlugin from "@allurereport/plugin-server-reload";
6
11
  import { PathResultFile } from "@allurereport/reader-api";
7
12
  import { serve } from "@allurereport/static-server";
8
13
  import { Command, Option } from "clipanion";
9
- import * as console from "node:console";
10
- import { existsSync } from "node:fs";
11
- import { rm } from "node:fs/promises";
12
- import { join, resolve } from "node:path";
13
- import process, { exit } from "node:process";
14
14
  import { red } from "yoctocolors";
15
15
  export class WatchCommand extends Command {
16
16
  constructor() {
@@ -1,8 +1,8 @@
1
+ import * as console from "node:console";
2
+ import { exit } from "node:process";
1
3
  import { readConfig } from "@allurereport/core";
2
4
  import { AllureServiceClient, KnownError } from "@allurereport/service";
3
5
  import { Command, Option } from "clipanion";
4
- import * as console from "node:console";
5
- import { exit } from "node:process";
6
6
  import { green, red } from "yoctocolors";
7
7
  import { logError } from "../utils/logs.js";
8
8
  export class WhoamiCommand extends Command {
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import { Builtins, Cli } from "clipanion";
2
1
  import { readFileSync } from "node:fs";
3
2
  import { argv } from "node:process";
3
+ import { Builtins, Cli } from "clipanion";
4
4
  import { Allure2Command, AwesomeCommand, ClassicCommand, CsvCommand, DashboardCommand, GenerateCommand, HistoryCommand, JiraClearCommand, KnownIssueCommand, LogCommand, OpenCommand, QualityGateCommand, ResultsPackCommand, ResultsUnpackCommand, RunCommand, SlackCommand, TestPlanCommand, WatchCommand, WhoamiCommand, } from "./commands/index.js";
5
5
  const [node, app, ...args] = argv;
6
6
  const pkg = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8"));
@@ -0,0 +1,16 @@
1
+ import { type FullConfig } from "@allurereport/core";
2
+ import type { EnvironmentIdentity } from "@allurereport/core-api";
3
+ type CommandEnvironmentOptions = {
4
+ environment?: string;
5
+ environmentName?: string;
6
+ };
7
+ export declare const environmentOption: () => string | undefined;
8
+ export declare const environmentNameOption: () => string | undefined;
9
+ export declare const resolveCommandEnvironment: (config: Pick<FullConfig, "environment" | "environments">, options: CommandEnvironmentOptions & {
10
+ source?: string;
11
+ }) => EnvironmentIdentity | undefined;
12
+ export declare const normalizeCommandEnvironmentOptions: (options: CommandEnvironmentOptions) => {
13
+ environment: string | undefined;
14
+ environmentName: string | undefined;
15
+ };
16
+ export {};
@@ -0,0 +1,64 @@
1
+ import { environmentIdentityById, environmentIdentityByName } from "@allurereport/core";
2
+ import { validateEnvironmentId, validateEnvironmentName } from "@allurereport/core-api";
3
+ import { Option, UsageError } from "clipanion";
4
+ const environmentOptionDescription = "Force specific environment ID to all tests in the run. Given environment has higher priority than the one defined in the config file (default: empty string)";
5
+ const environmentNameOptionDescription = "Force specific environment display name to all tests in the run. Has lower priority than --environment and higher priority than the config value (default: empty string)";
6
+ export const environmentOption = () => Option.String("--environment,--env", {
7
+ description: environmentOptionDescription,
8
+ });
9
+ export const environmentNameOption = () => Option.String("--environment-name", {
10
+ description: environmentNameOptionDescription,
11
+ });
12
+ const resolveEnvironmentByName = (config, environmentName, source) => {
13
+ const identity = environmentIdentityByName(config.environments ?? {}, environmentName);
14
+ if (!identity) {
15
+ throw new UsageError(`${source}: environment name ${JSON.stringify(environmentName)} does not match any configured environment`);
16
+ }
17
+ return identity;
18
+ };
19
+ const resolveConfigEnvironment = (config) => {
20
+ if (config.environment === undefined) {
21
+ return undefined;
22
+ }
23
+ return (environmentIdentityById(config.environments ?? {}, config.environment) ??
24
+ environmentIdentityByName(config.environments ?? {}, config.environment) ?? {
25
+ id: config.environment,
26
+ name: config.environment,
27
+ });
28
+ };
29
+ export const resolveCommandEnvironment = (config, options) => {
30
+ const source = options.source ?? "cli";
31
+ const { environment, environmentName } = normalizeCommandEnvironmentOptions(options);
32
+ const identityFromId = environment !== undefined
33
+ ? (environmentIdentityById(config.environments ?? {}, environment) ?? { id: environment, name: environment })
34
+ : undefined;
35
+ const identityFromName = environmentName !== undefined ? resolveEnvironmentByName(config, environmentName, source) : undefined;
36
+ const configIdentity = resolveConfigEnvironment(config);
37
+ if (identityFromId && identityFromName && identityFromId.id !== identityFromName.id) {
38
+ throw new UsageError(`${source}: environment id ${JSON.stringify(identityFromId.id)} and environment name ${JSON.stringify(identityFromName.name)} resolve to different environments`);
39
+ }
40
+ const identity = identityFromId ?? identityFromName ?? configIdentity;
41
+ return identity;
42
+ };
43
+ export const normalizeCommandEnvironmentOptions = (options) => {
44
+ let environment;
45
+ let environmentName;
46
+ if (typeof options.environment === "string") {
47
+ const validation = validateEnvironmentId(options.environment);
48
+ if (!validation.valid) {
49
+ throw new UsageError(`Invalid --environment value ${JSON.stringify(options.environment)}: ${validation.reason}`);
50
+ }
51
+ environment = validation.normalized;
52
+ }
53
+ if (typeof options.environmentName === "string") {
54
+ const validation = validateEnvironmentName(options.environmentName);
55
+ if (!validation.valid) {
56
+ throw new UsageError(`Invalid --environment-name value ${JSON.stringify(options.environmentName)}: ${validation.reason}`);
57
+ }
58
+ environmentName = validation.normalized;
59
+ }
60
+ return {
61
+ environment,
62
+ environmentName,
63
+ };
64
+ };
@@ -1,7 +1,7 @@
1
- import { invokeStdoutCliTool } from "@allurereport/reader-api";
2
1
  import { spawn } from "node:child_process";
3
2
  import process from "node:process";
4
3
  import { platform } from "process";
4
+ import { invokeStdoutCliTool } from "@allurereport/reader-api";
5
5
  const IS_WIN = platform === "win32";
6
6
  const PS_OUTPUT_PATTERN = /(?<ppid>\d+)\s+(?<pid>\d+)\s+(?<comm>.*)/;
7
7
  export const runProcess = (params) => {
@@ -1,5 +1,5 @@
1
- import { formatDuration } from "@allurereport/core-api";
2
1
  import console from "node:console";
2
+ import { formatDuration } from "@allurereport/core-api";
3
3
  import { blue, gray, green, red, yellow } from "yoctocolors";
4
4
  export const status2color = (status) => {
5
5
  switch (status) {
package/package.json CHANGED
@@ -1,56 +1,56 @@
1
1
  {
2
2
  "name": "allure",
3
- "version": "3.3.1",
3
+ "version": "3.4.1",
4
4
  "description": "Allure Commandline Tool",
5
5
  "keywords": [
6
6
  "allure",
7
- "testing",
8
- "report"
7
+ "report",
8
+ "testing"
9
9
  ],
10
- "repository": "https://github.com/allure-framework/allure3",
11
10
  "license": "Apache-2.0",
12
11
  "author": "Qameta Software",
12
+ "repository": "https://github.com/allure-framework/allure3",
13
+ "bin": "./cli.js",
14
+ "files": [
15
+ "./dist"
16
+ ],
13
17
  "type": "module",
18
+ "main": "./dist/index.js",
19
+ "module": "./dist/index.js",
20
+ "types": "./dist/index.d.ts",
14
21
  "exports": {
15
22
  ".": "./dist/index.js",
16
23
  "./rules": "./dist/rules.js",
17
24
  "./qualityGate": "./dist/qualityGate.js"
18
25
  },
19
- "main": "./dist/index.js",
20
- "module": "./dist/index.js",
21
- "types": "./dist/index.d.ts",
22
- "bin": "./cli.js",
23
- "files": [
24
- "./dist"
25
- ],
26
26
  "scripts": {
27
27
  "build": "run clean && tsc --project ./tsconfig.json",
28
28
  "clean": "rimraf ./dist",
29
- "eslint": "eslint ./src/**/*.{js,jsx,ts,tsx}",
30
- "eslint:format": "eslint --fix ./src/**/*.{js,jsx,ts,tsx}",
31
29
  "start": "node ./cli.js",
32
- "test": "vitest run"
30
+ "test": "vitest run",
31
+ "lint": "oxlint --import-plugin src test features stories",
32
+ "lint:fix": "oxlint --import-plugin --fix src test features stories"
33
33
  },
34
34
  "dependencies": {
35
- "@allurereport/charts-api": "3.3.1",
36
- "@allurereport/ci": "3.3.1",
37
- "@allurereport/core": "3.3.1",
38
- "@allurereport/core-api": "3.3.1",
39
- "@allurereport/directory-watcher": "3.3.1",
40
- "@allurereport/plugin-allure2": "3.3.1",
41
- "@allurereport/plugin-api": "3.3.1",
42
- "@allurereport/plugin-awesome": "3.3.1",
43
- "@allurereport/plugin-classic": "3.3.1",
44
- "@allurereport/plugin-csv": "3.3.1",
45
- "@allurereport/plugin-dashboard": "3.3.1",
46
- "@allurereport/plugin-jira": "3.3.1",
47
- "@allurereport/plugin-log": "3.3.1",
48
- "@allurereport/plugin-progress": "3.3.1",
49
- "@allurereport/plugin-server-reload": "3.3.1",
50
- "@allurereport/plugin-slack": "3.3.1",
51
- "@allurereport/reader-api": "3.3.1",
52
- "@allurereport/service": "3.3.1",
53
- "@allurereport/static-server": "3.3.1",
35
+ "@allurereport/charts-api": "3.4.1",
36
+ "@allurereport/ci": "3.4.1",
37
+ "@allurereport/core": "3.4.1",
38
+ "@allurereport/core-api": "3.4.1",
39
+ "@allurereport/directory-watcher": "3.4.1",
40
+ "@allurereport/plugin-allure2": "3.4.1",
41
+ "@allurereport/plugin-api": "3.4.1",
42
+ "@allurereport/plugin-awesome": "3.4.1",
43
+ "@allurereport/plugin-classic": "3.4.1",
44
+ "@allurereport/plugin-csv": "3.4.1",
45
+ "@allurereport/plugin-dashboard": "3.4.1",
46
+ "@allurereport/plugin-jira": "3.4.1",
47
+ "@allurereport/plugin-log": "3.4.1",
48
+ "@allurereport/plugin-progress": "3.4.1",
49
+ "@allurereport/plugin-server-reload": "3.4.1",
50
+ "@allurereport/plugin-slack": "3.4.1",
51
+ "@allurereport/reader-api": "3.4.1",
52
+ "@allurereport/service": "3.4.1",
53
+ "@allurereport/static-server": "3.4.1",
54
54
  "adm-zip": "^0.5.16",
55
55
  "clipanion": "^4.0.0-rc.4",
56
56
  "glob": "^11.1.0",
@@ -60,24 +60,13 @@
60
60
  "yoctocolors": "^2.1.1"
61
61
  },
62
62
  "devDependencies": {
63
- "@stylistic/eslint-plugin": "^2.6.1",
64
63
  "@types/adm-zip": "^0",
65
- "@types/eslint": "^8.56.11",
66
64
  "@types/lodash.omit": "^4.5.9",
67
65
  "@types/node": "^20.17.9",
68
66
  "@types/prompts": "^2",
69
- "@typescript-eslint/eslint-plugin": "^8.0.0",
70
- "@typescript-eslint/parser": "^8.0.0",
71
67
  "@vitest/runner": "^2.1.9",
72
68
  "@vitest/snapshot": "^2.1.9",
73
69
  "allure-vitest": "^3.3.3",
74
- "eslint": "^8.57.0",
75
- "eslint-config-prettier": "^9.1.0",
76
- "eslint-plugin-import": "^2.29.1",
77
- "eslint-plugin-jsdoc": "^50.0.0",
78
- "eslint-plugin-n": "^17.10.1",
79
- "eslint-plugin-no-null": "^1.0.2",
80
- "eslint-plugin-prefer-arrow": "^1.2.3",
81
70
  "rimraf": "^6.0.1",
82
71
  "typescript": "^5.6.3",
83
72
  "vitest": "^2.1.9"