allure 3.16.0 → 3.17.0

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.
@@ -197,11 +197,9 @@ export const executeAgentMode = async (params) => {
197
197
  realTime: false,
198
198
  plugins: [...humanReport.plugins, ...(config.plugins ?? [])],
199
199
  });
200
- const knownIssues = await allureReport.store.allKnownIssues();
201
200
  const resultsPatterns = resolveResultsPatterns(cliResultsPatterns, config.resultsDir);
202
201
  const { globalExitCode } = await executeAllureRun({
203
202
  allureReport,
204
- knownIssues,
205
203
  cwd,
206
204
  command,
207
205
  commandArgs,
@@ -47,7 +47,7 @@ export class Allure2Command extends Command {
47
47
  const config = await readConfig(cwd, this.config, {
48
48
  output: this.output,
49
49
  name: this.reportName,
50
- knownIssuesPath: this.knownIssues,
50
+ resolutions: { knownIssuesPath: this.knownIssues },
51
51
  historyPath: this.historyPath,
52
52
  });
53
53
  const { resultDirectories, patterns } = await resolveAndFindResultsDirs(cwd, this.resultsDir, config.resultsDir);
@@ -56,7 +56,7 @@ export class AwesomeCommand extends Command {
56
56
  const config = await readConfig(cwd, this.config, {
57
57
  output: this.output,
58
58
  name: this.reportName,
59
- knownIssuesPath: this.knownIssues,
59
+ resolutions: { knownIssuesPath: this.knownIssues },
60
60
  historyPath: this.historyPath,
61
61
  hideLabels,
62
62
  });
@@ -47,7 +47,7 @@ export class ClassicCommand extends Command {
47
47
  const config = await readConfig(cwd, this.config, {
48
48
  output: this.output,
49
49
  name: this.reportName,
50
- knownIssuesPath: this.knownIssues,
50
+ resolutions: { knownIssuesPath: this.knownIssues },
51
51
  historyPath: this.historyPath,
52
52
  });
53
53
  const { resultDirectories, patterns } = await resolveAndFindResultsDirs(cwd, this.resultsDir, config.resultsDir);
@@ -1,5 +1,4 @@
1
1
  import { AllureReport } from "@allurereport/core";
2
- import { type KnownTestFailure } from "@allurereport/core-api";
3
2
  import type { ExitCode, QualityGateValidationResult } from "@allurereport/plugin-api";
4
3
  export type TestProcessResult = {
5
4
  code: number | null;
@@ -18,7 +17,6 @@ export declare const executeNestedAllureCommand: (params: {
18
17
  }) => Promise<number | null>;
19
18
  export declare const runTests: (params: {
20
19
  allureReport: AllureReport;
21
- knownIssues: KnownTestFailure[];
22
20
  cwd: string;
23
21
  command: string;
24
22
  commandArgs: string[];
@@ -32,7 +30,6 @@ export declare const runTests: (params: {
32
30
  }) => Promise<TestProcessResult | null>;
33
31
  export declare const executeAllureRun: (params: {
34
32
  allureReport: AllureReport;
35
- knownIssues: KnownTestFailure[];
36
33
  cwd: string;
37
34
  command: string;
38
35
  commandArgs: string[];
@@ -34,7 +34,7 @@ const attachResultsDirectoryWatchers = (params) => {
34
34
  return allureResultsDirectoriesWatcher(params.cwd, params.onUpdate, { indexDelay: 600 });
35
35
  };
36
36
  export const runTests = async (params) => {
37
- const { allureReport, knownIssues, cwd, command, commandArgs, logs, environmentVariables, environment, withQualityGate, silent, logProcessExit = true, resultsPatterns = [], } = params;
37
+ const { allureReport, cwd, command, commandArgs, logs, environmentVariables, environment, withQualityGate, silent, logProcessExit = true, resultsPatterns = [], } = params;
38
38
  let testProcessStarted = false;
39
39
  const allureResultsWatchers = new Map();
40
40
  const processWatcher = delayedFileProcessingWatcher(async (path) => {
@@ -99,7 +99,6 @@ export const runTests = async (params) => {
99
99
  trs: filteredTrs,
100
100
  state: qualityGateState,
101
101
  environment,
102
- knownIssues,
103
102
  });
104
103
  if (!fastFailed) {
105
104
  return;
@@ -161,7 +160,7 @@ export const runTests = async (params) => {
161
160
  };
162
161
  };
163
162
  export const executeAllureRun = async (params) => {
164
- const { allureReport, knownIssues, cwd, command, commandArgs, environmentVariables = {}, environment, withQualityGate, silent, logs, ignoreLogs, maxRerun = 0, logProcessExit = true, resultsPatterns = [], } = params;
163
+ const { allureReport, cwd, command, commandArgs, environmentVariables = {}, environment, withQualityGate, silent, logs, ignoreLogs, maxRerun = 0, logProcessExit = true, resultsPatterns = [], } = params;
165
164
  await allureReport.start();
166
165
  const globalExitCode = {
167
166
  original: 0,
@@ -174,7 +173,6 @@ export const executeAllureRun = async (params) => {
174
173
  logs,
175
174
  silent,
176
175
  allureReport,
177
- knownIssues,
178
176
  cwd,
179
177
  command,
180
178
  commandArgs,
@@ -205,7 +203,6 @@ export const executeAllureRun = async (params) => {
205
203
  silent,
206
204
  logs,
207
205
  allureReport,
208
- knownIssues,
209
206
  cwd,
210
207
  command,
211
208
  commandArgs,
@@ -232,7 +229,6 @@ export const executeAllureRun = async (params) => {
232
229
  if (withQualityGate && !qualityGateResults.length) {
233
230
  const { results } = await allureReport.validate({
234
231
  trs,
235
- knownIssues,
236
232
  environment,
237
233
  });
238
234
  qualityGateResults = results;
@@ -41,7 +41,7 @@ export class CsvCommand extends Command {
41
41
  fileName: this.output && isAbsolute(this.output) ? this.output : this.output ? join(cwd, this.output) : undefined,
42
42
  };
43
43
  const config = await readConfig(cwd, this.config, {
44
- knownIssuesPath: this.knownIssues,
44
+ resolutions: { knownIssuesPath: this.knownIssues },
45
45
  });
46
46
  const { resultDirectories, patterns } = await resolveAndFindResultsDirs(cwd, this.resultsDir, config.resultsDir);
47
47
  if (!resultDirectories.length) {
@@ -39,7 +39,8 @@ export class GenerateCommand extends Command {
39
39
  description: "Hide labels by exact name in generated reports. Repeat the option for multiple labels",
40
40
  });
41
41
  this.knownIssues = Option.String("--known-issues", {
42
- description: "Path to known issues file",
42
+ description: "Path to known issues file. " +
43
+ "Allure loads the file and updates it every time with the actual resolutions data of type `issue`",
43
44
  });
44
45
  }
45
46
  async execute() {
@@ -52,7 +53,7 @@ export class GenerateCommand extends Command {
52
53
  port: this.port,
53
54
  hideLabels,
54
55
  historyLimit: this.historyLimit !== undefined ? parseInt(this.historyLimit, 10) : undefined,
55
- knownIssuesPath: this.knownIssues,
56
+ resolutions: { knownIssuesPath: this.knownIssues },
56
57
  });
57
58
  await generate({
58
59
  dump: this.dump,
@@ -10,6 +10,7 @@ export * from "./history.js";
10
10
  export * from "./run.js";
11
11
  export * from "./slack.js";
12
12
  export * from "./testplan.js";
13
+ export * from "./testopsPlan.js";
13
14
  export * from "./watch.js";
14
15
  export * from "./open.js";
15
16
  export * from "./qualityGate.js";
@@ -10,6 +10,7 @@ export * from "./history.js";
10
10
  export * from "./run.js";
11
11
  export * from "./slack.js";
12
12
  export * from "./testplan.js";
13
+ export * from "./testopsPlan.js";
13
14
  export * from "./watch.js";
14
15
  export * from "./open.js";
15
16
  export * from "./qualityGate.js";
@@ -49,7 +49,7 @@ export class QualityGateCommand extends Command {
49
49
  const cwd = await realpath(this.cwd ?? processCwd());
50
50
  const { maxFailures, minTestsCount, successRate, fastFail } = this;
51
51
  const config = await readConfig(cwd, this.config, {
52
- knownIssuesPath: this.knownIssues,
52
+ resolutions: { knownIssuesPath: this.knownIssues },
53
53
  });
54
54
  const resolvedEnvironment = resolveCommandEnvironment(config, environmentOptions);
55
55
  const rules = {};
@@ -87,7 +87,6 @@ export class QualityGateCommand extends Command {
87
87
  exit(1);
88
88
  return;
89
89
  }
90
- const knownIssues = await allureReport.store.allKnownIssues();
91
90
  const state = new QualityGateState();
92
91
  allureReport.realtimeSubscriber.onTestResults(async (trsIds) => {
93
92
  const trs = await Promise.all(trsIds.map((id) => allureReport.store.testResultById(id)));
@@ -95,7 +94,6 @@ export class QualityGateCommand extends Command {
95
94
  const { results, fastFailed } = await allureReport.validate({
96
95
  trs: nonRetryTrs,
97
96
  environment: resolvedEnvironment?.id,
98
- knownIssues,
99
97
  state,
100
98
  });
101
99
  if (!fastFailed) {
@@ -112,7 +110,6 @@ export class QualityGateCommand extends Command {
112
110
  const allTrs = await allureReport.store.allTestResults({ includeRetries: false });
113
111
  const validationResults = await allureReport.validate({
114
112
  trs: allTrs,
115
- knownIssues,
116
113
  environment: resolvedEnvironment?.id,
117
114
  });
118
115
  if (validationResults.results.length === 0) {
@@ -101,7 +101,7 @@ export class RunCommand extends Command {
101
101
  port: this.port,
102
102
  hideLabels,
103
103
  historyLimit: this.historyLimit !== undefined ? parseInt(this.historyLimit, 10) : undefined,
104
- knownIssuesPath: this.knownIssues,
104
+ resolutions: { knownIssuesPath: this.knownIssues },
105
105
  });
106
106
  const resultsPatterns = resolveResultsPatterns(this.resultsDir ?? [], config.resultsDir);
107
107
  const resolvedEnvironment = resolveCommandEnvironment(config, environmentOptions);
@@ -139,10 +139,8 @@ export class RunCommand extends Command {
139
139
  ]),
140
140
  ],
141
141
  });
142
- const knownIssues = await allureReport.store.allKnownIssues();
143
142
  const { globalExitCode } = await executeAllureRun({
144
143
  allureReport,
145
- knownIssues,
146
144
  cwd,
147
145
  command,
148
146
  commandArgs,
@@ -0,0 +1,7 @@
1
+ import { Command } from "clipanion";
2
+ export declare class TestOpsPlanCommand extends Command {
3
+ static paths: string[][];
4
+ static usage: import("clipanion").Usage;
5
+ output: string | undefined;
6
+ execute(): Promise<void>;
7
+ }
@@ -0,0 +1,65 @@
1
+ import * as console from "node:console";
2
+ import { rm, writeFile } from "node:fs/promises";
3
+ import { resolve } from "node:path";
4
+ import { env, exit } from "node:process";
5
+ import { applyAllureCiEnv } from "@allurereport/ci";
6
+ import { createServiceHttpClient } from "@allurereport/service";
7
+ import { Command, Option } from "clipanion";
8
+ import { red } from "yoctocolors";
9
+ export class TestOpsPlanCommand extends Command {
10
+ constructor() {
11
+ super(...arguments);
12
+ this.output = Option.String("--output,-o", {
13
+ description: "The output file name. Absolute paths are accepted as well (default: ./testplan.json)",
14
+ });
15
+ }
16
+ async execute() {
17
+ applyAllureCiEnv();
18
+ const jobRunId = Number(env.ALLURE_JOB_RUN_ID);
19
+ if (!Number.isInteger(jobRunId) || jobRunId <= 0) {
20
+ console.log("ALLURE_JOB_RUN_ID isn't set, skipping test plan generation");
21
+ return;
22
+ }
23
+ const endpoint = env.ALLURE_ENDPOINT;
24
+ const accessToken = env.ALLURE_TOKEN;
25
+ if (!endpoint || !accessToken) {
26
+ console.error(red("ALLURE_ENDPOINT and ALLURE_TOKEN are required to fetch a test plan from TestOps"));
27
+ exit(1);
28
+ return;
29
+ }
30
+ const client = createServiceHttpClient(endpoint, { apiToken: accessToken });
31
+ const output = resolve(this.output ?? "./testplan.json");
32
+ let tests;
33
+ try {
34
+ tests = await client.get(`/api/rs/jobrun/${jobRunId}/plan`, {
35
+ params: { expected: "true" },
36
+ });
37
+ }
38
+ catch (error) {
39
+ const message = error instanceof Error ? error.message : String(error);
40
+ await rm(output, { force: true });
41
+ console.error(red(`Could not fetch the test plan for job run ${jobRunId}, continuing without one: ${message}`));
42
+ return;
43
+ }
44
+ const testPlan = {
45
+ version: "1.0",
46
+ tests: (tests ?? []).map(({ id, selector }) => ({
47
+ ...(id !== undefined ? { id: String(id) } : {}),
48
+ ...(selector !== undefined ? { selector } : {}),
49
+ })),
50
+ };
51
+ await writeFile(output, JSON.stringify(testPlan), "utf-8");
52
+ console.log(`test plan for job run ${jobRunId} written to ${output} (${testPlan.tests.length} test(s))`);
53
+ }
54
+ }
55
+ TestOpsPlanCommand.paths = [["testops-plan"]];
56
+ TestOpsPlanCommand.usage = Command.Usage({
57
+ description: "Fetches a testplan.json for the current TestOps job run",
58
+ details: "Reads ALLURE_JOB_RUN_ID and, when it's set, downloads the test cases selected for that job run " +
59
+ "from TestOps and writes them as a testplan.json compatible with ALLURE_TESTPLAN_PATH. " +
60
+ "Does nothing when ALLURE_JOB_RUN_ID isn't set, which covers every run TestOps didn't trigger itself.",
61
+ examples: [
62
+ ["testops-plan", "Write ./testplan.json from the current job run, if any"],
63
+ ["testops-plan --output custom-testplan.json", "Write to a custom path instead"],
64
+ ],
65
+ });
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { readFileSync } from "node:fs";
2
2
  import process, { argv } from "node:process";
3
3
  import { Builtins, Cli } from "clipanion";
4
- import { AgentCommand, AGENT_TASK_MAP_HELP, AgentCapabilitiesCommand, AgentInspectCommand, AgentLatestCommand, AgentQueryCommand, AgentSelectCommand, AgentStateDirCommand, Allure2Command, AwesomeCommand, CheckCommand, ClassicCommand, CsvCommand, DashboardCommand, GenerateCommand, HistoryCommand, JiraClearCommand, LogCommand, OpenCommand, QualityGateCommand, ResultsPackCommand, ResultsUnpackCommand, RunCommand, SlackCommand, TestPlanCommand, WatchCommand, isAgentTaskMapHelpRequest, } from "./commands/index.js";
4
+ import { AgentCommand, AGENT_TASK_MAP_HELP, AgentCapabilitiesCommand, AgentInspectCommand, AgentLatestCommand, AgentQueryCommand, AgentSelectCommand, AgentStateDirCommand, Allure2Command, AwesomeCommand, CheckCommand, ClassicCommand, CsvCommand, DashboardCommand, GenerateCommand, HistoryCommand, JiraClearCommand, LogCommand, OpenCommand, QualityGateCommand, ResultsPackCommand, ResultsUnpackCommand, RunCommand, SlackCommand, TestOpsPlanCommand, TestPlanCommand, WatchCommand, isAgentTaskMapHelpRequest, } 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"));
7
7
  const cli = new Cli({
@@ -30,6 +30,7 @@ cli.register(OpenCommand);
30
30
  cli.register(QualityGateCommand);
31
31
  cli.register(RunCommand);
32
32
  cli.register(SlackCommand);
33
+ cli.register(TestOpsPlanCommand);
33
34
  cli.register(TestPlanCommand);
34
35
  cli.register(WatchCommand);
35
36
  cli.register(ResultsPackCommand);
package/dist/rules.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export { qualityGateDefaultRules, maxFailuresRule, minTestsCountRule, successRateRule } from "@allurereport/core";
1
+ export { qualityGateDefaultRules, maxFailuresRule, minTestsCountRule, successRateRule, metricMaxRule, metricMinRule, metricMaxDeltaRule, metricMaxDeltaPercentRule, } from "@allurereport/core";
2
2
  export type { QualityGateRule, QualityGateRuleState, QualityGateValidationResult } from "@allurereport/plugin-api";
package/dist/rules.js CHANGED
@@ -1 +1 @@
1
- export { qualityGateDefaultRules, maxFailuresRule, minTestsCountRule, successRateRule } from "@allurereport/core";
1
+ export { qualityGateDefaultRules, maxFailuresRule, minTestsCountRule, successRateRule, metricMaxRule, metricMinRule, metricMaxDeltaRule, metricMaxDeltaPercentRule, } from "@allurereport/core";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "allure",
3
- "version": "3.16.0",
3
+ "version": "3.17.0",
4
4
  "description": "Allure Commandline Tool",
5
5
  "keywords": [
6
6
  "allure",
@@ -32,26 +32,26 @@
32
32
  "lint:fix": "oxlint --import-plugin --fix src test features stories"
33
33
  },
34
34
  "dependencies": {
35
- "@allurereport/charts-api": "3.16.0",
36
- "@allurereport/ci": "3.16.0",
37
- "@allurereport/core": "3.16.0",
38
- "@allurereport/core-api": "3.16.0",
39
- "@allurereport/directory-watcher": "3.16.0",
40
- "@allurereport/plugin-agent": "3.16.0",
41
- "@allurereport/plugin-allure2": "3.16.0",
42
- "@allurereport/plugin-api": "3.16.0",
43
- "@allurereport/plugin-awesome": "3.16.0",
44
- "@allurereport/plugin-classic": "3.16.0",
45
- "@allurereport/plugin-csv": "3.16.0",
46
- "@allurereport/plugin-dashboard": "3.16.0",
47
- "@allurereport/plugin-jira": "3.16.0",
48
- "@allurereport/plugin-log": "3.16.0",
49
- "@allurereport/plugin-progress": "3.16.0",
50
- "@allurereport/plugin-server-reload": "3.16.0",
51
- "@allurereport/plugin-slack": "3.16.0",
52
- "@allurereport/reader-api": "3.16.0",
53
- "@allurereport/service": "3.16.0",
54
- "@allurereport/static-server": "3.16.0",
35
+ "@allurereport/charts-api": "3.17.0",
36
+ "@allurereport/ci": "3.17.0",
37
+ "@allurereport/core": "3.17.0",
38
+ "@allurereport/core-api": "3.17.0",
39
+ "@allurereport/directory-watcher": "3.17.0",
40
+ "@allurereport/plugin-agent": "3.17.0",
41
+ "@allurereport/plugin-allure2": "3.17.0",
42
+ "@allurereport/plugin-api": "3.17.0",
43
+ "@allurereport/plugin-awesome": "3.17.0",
44
+ "@allurereport/plugin-classic": "3.17.0",
45
+ "@allurereport/plugin-csv": "3.17.0",
46
+ "@allurereport/plugin-dashboard": "3.17.0",
47
+ "@allurereport/plugin-jira": "3.17.0",
48
+ "@allurereport/plugin-log": "3.17.0",
49
+ "@allurereport/plugin-progress": "3.17.0",
50
+ "@allurereport/plugin-server-reload": "3.17.0",
51
+ "@allurereport/plugin-slack": "3.17.0",
52
+ "@allurereport/reader-api": "3.17.0",
53
+ "@allurereport/service": "3.17.0",
54
+ "@allurereport/static-server": "3.17.0",
55
55
  "adm-zip": "^0.6.0",
56
56
  "clipanion": "^4.0.0-rc.4",
57
57
  "glob": "^13.0.6",