allure 3.15.0 → 3.16.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.
- package/README.md +16 -7
- package/dist/commands/agent-run.d.ts +1 -0
- package/dist/commands/agent-run.js +11 -6
- package/dist/commands/agent.d.ts +1 -0
- package/dist/commands/agent.js +19 -8
- package/dist/commands/allure2.js +9 -9
- package/dist/commands/awesome.js +9 -9
- package/dist/commands/check.js +1 -1
- package/dist/commands/classic.js +9 -9
- package/dist/commands/commons/generate.d.ts +1 -1
- package/dist/commands/commons/generate.js +7 -3
- package/dist/commands/commons/resultsDiscovery.d.ts +5 -0
- package/dist/commands/commons/resultsDiscovery.js +17 -0
- package/dist/commands/commons/run.d.ts +2 -0
- package/dist/commands/commons/run.js +37 -22
- package/dist/commands/csv.js +9 -9
- package/dist/commands/dashboard.js +9 -9
- package/dist/commands/generate.js +2 -2
- package/dist/commands/history.js +6 -4
- package/dist/commands/jira/clear.js +1 -1
- package/dist/commands/log.js +9 -9
- package/dist/commands/open.js +9 -5
- package/dist/commands/qualityGate.js +4 -4
- package/dist/commands/results/pack.d.ts +1 -0
- package/dist/commands/results/pack.js +12 -14
- package/dist/commands/run.d.ts +1 -0
- package/dist/commands/run.js +19 -7
- package/dist/commands/slack.js +9 -9
- package/dist/commands/testplan.js +7 -5
- package/dist/commands/watch.d.ts +1 -0
- package/dist/commands/watch.js +71 -25
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.js +2 -0
- package/dist/utils/process.js +1 -0
- package/dist/utils/resultsPatterns.d.ts +12 -0
- package/dist/utils/resultsPatterns.js +37 -0
- package/dist/utils/signals.d.ts +18 -0
- package/dist/utils/signals.js +52 -0
- package/package.json +21 -21
package/README.md
CHANGED
|
@@ -56,7 +56,15 @@ To hide specific labels use `--hide-labels` option:
|
|
|
56
56
|
npx allure run --hide-labels=owner --hide-labels=tag -- npm test
|
|
57
57
|
```
|
|
58
58
|
|
|
59
|
-
To successfully generate a report, ensure that your test setup outputs results into an `allure-results` directory
|
|
59
|
+
To successfully generate a report, ensure that your test setup outputs results into an `allure-results` directory. With `allure run` / `allure agent` / empty `allure watch`, directories named `allure-results` are discovered dynamically (name-based watcher). With one-shot commands such as `allure generate`, an empty CLI and unset `config.resultsDir` default to the `./**/allure-results` glob. Quote globs in the shell so they are not expanded early.
|
|
60
|
+
|
|
61
|
+
You can also set `resultsDir` in the Allure config (`string | string[]`) or pass `--results-dir` on `run` / `agent`:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
npx allure run --open --results-dir './artifacts/**/allure-results' -- npm test
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Repeat `--results-dir` for multiple patterns. CLI overrides `config.resultsDir`.
|
|
60
68
|
|
|
61
69
|
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.
|
|
62
70
|
|
|
@@ -191,7 +199,7 @@ export default defineConfig({
|
|
|
191
199
|
});
|
|
192
200
|
```
|
|
193
201
|
|
|
194
|
-
In this example, the generated report is named
|
|
202
|
+
In this example, the generated report is named _Allure Report Example_ and saved to the `./out/allure-report` directory. The **Awesome** plugin is enabled with options to produce a single-file HTML report in English.
|
|
195
203
|
|
|
196
204
|
### TypeScript Configuration File
|
|
197
205
|
|
|
@@ -214,17 +222,18 @@ The configuration file allows you to fine-tune report generation. Key options in
|
|
|
214
222
|
|
|
215
223
|
- **`name`**: Specifies the report’s display name.
|
|
216
224
|
- **`output`**: Defines the directory where the report will be saved.
|
|
217
|
-
- **`
|
|
225
|
+
- **`resultsDir`** _(`string | string[]`)_: Glob patterns or paths used when reading Allure results directories. For one-shot commands, CLI positionals override this value. For `allure run` / `allure agent`, use repeated `--results-dir` (same override priority). When both CLI and `resultsDir` are empty, one-shot commands (`generate`, etc.) use `./**/allure-results`, while live commands (`run`, `agent`, empty `watch`) use name-based discovery of directories named `allure-results`. Quote globs in the shell.
|
|
226
|
+
- **`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.
|
|
218
227
|
- **`plugins`**: Enables and configures plugins, with each supporting various options.
|
|
219
228
|
|
|
220
229
|
### Awesome Plugin Options
|
|
221
230
|
|
|
222
231
|
The **Awesome** plugin offers several customizable options:
|
|
223
232
|
|
|
224
|
-
- **`singleFile`**
|
|
225
|
-
- **`reportName`**
|
|
226
|
-
- **`open`**
|
|
227
|
-
- **`reportLanguage`**
|
|
233
|
+
- **`singleFile`** _(boolean)_: If set to `true`, generates the report as a single standalone HTML file.
|
|
234
|
+
- **`reportName`** _(string)_: Overrides the default report name.
|
|
235
|
+
- **`open`** _(boolean)_: Automatically opens the report after generation if enabled.
|
|
236
|
+
- **`reportLanguage`** _(string)_: Sets the UI language of the report. Supported languages include:
|
|
228
237
|
|
|
229
238
|
`az`, `br`, `de`, `en`, `es`, `fr`, `he`, `ja`, `kr`, `nl`, `pl`, `ru`, `sv`, `tr`, `zh`.
|
|
230
239
|
|
|
@@ -32,6 +32,7 @@ export type ExecuteAgentModeParams = {
|
|
|
32
32
|
rerunLabels?: string[];
|
|
33
33
|
reportMode: AgentHumanReportMode;
|
|
34
34
|
args: string[];
|
|
35
|
+
resultsPatterns?: readonly string[];
|
|
35
36
|
};
|
|
36
37
|
export declare const executeAgentMode: (params: ExecuteAgentModeParams) => Promise<void>;
|
|
37
38
|
export type ExecuteAgentInspectModeParams = {
|
|
@@ -8,7 +8,8 @@ import { AllureReport, isFileNotFoundError, readConfig } from "@allurereport/cor
|
|
|
8
8
|
import { createAgentTestPlanContext, AgentUsageError, assertExplicitAgentOutputDirIsSafe, formatAgentOutputLinks, formatAgentRunSummary, isPathInside, loadAgentOutput, normalizeAgentRerunPreset, parseAgentLabelFilters, cleanupAgentRunState, cleanupStaleAgentRunStates, resolveAgentStateDir, writeAgentRunState, } from "@allurereport/plugin-agent";
|
|
9
9
|
import { normalizeCommandEnvironmentOptions, resolveCommandEnvironment } from "../utils/environment.js";
|
|
10
10
|
import { createChildAllureCliEnvironment, getActiveAllureCliCommand } from "../utils/execution-context.js";
|
|
11
|
-
import {
|
|
11
|
+
import { findFilesByGlobs } from "../utils/fileSystem.js";
|
|
12
|
+
import { resolveAndFindResultsDirs, resolveResultsPatterns } from "../utils/resultsPatterns.js";
|
|
12
13
|
import { createAgentHumanReportConfig } from "./agent-human-report.js";
|
|
13
14
|
import { executeAllureRun, executeNestedAllureCommand } from "./commons/run.js";
|
|
14
15
|
export const formatAgentCommand = (args) => args.join(" ");
|
|
@@ -90,7 +91,7 @@ export const cleanupManagedAgentOutputs = async (params) => {
|
|
|
90
91
|
}
|
|
91
92
|
};
|
|
92
93
|
export const executeAgentMode = async (params) => {
|
|
93
|
-
const { configPath, cwd: configuredCwd, output, expectations, inlineExpectations, environment, environmentName, silent, rerunFrom, rerunLatest, rerunPreset, rerunEnvironments, rerunLabels, reportMode, args, } = params;
|
|
94
|
+
const { configPath, cwd: configuredCwd, output, expectations, inlineExpectations, environment, environmentName, silent, rerunFrom, rerunLatest, rerunPreset, rerunEnvironments, rerunLabels, reportMode, args, resultsPatterns: cliResultsPatterns = [], } = params;
|
|
94
95
|
const command = args[0];
|
|
95
96
|
const commandArgs = args.slice(1);
|
|
96
97
|
const cwd = await realpath(configuredCwd ?? process.cwd());
|
|
@@ -197,6 +198,7 @@ export const executeAgentMode = async (params) => {
|
|
|
197
198
|
plugins: [...humanReport.plugins, ...(config.plugins ?? [])],
|
|
198
199
|
});
|
|
199
200
|
const knownIssues = await allureReport.store.allKnownIssues();
|
|
201
|
+
const resultsPatterns = resolveResultsPatterns(cliResultsPatterns, config.resultsDir);
|
|
200
202
|
const { globalExitCode } = await executeAllureRun({
|
|
201
203
|
allureReport,
|
|
202
204
|
knownIssues,
|
|
@@ -210,6 +212,7 @@ export const executeAgentMode = async (params) => {
|
|
|
210
212
|
silent: true,
|
|
211
213
|
ignoreLogs: false,
|
|
212
214
|
logProcessExit: false,
|
|
215
|
+
resultsPatterns,
|
|
213
216
|
});
|
|
214
217
|
await persistAgentRunState({
|
|
215
218
|
runId,
|
|
@@ -240,13 +243,15 @@ export const executeAgentInspectMode = async (params) => {
|
|
|
240
243
|
const { configPath, cwd: configuredCwd, output, expectations, inlineExpectations, environment, environmentName, reportName, open, port, historyLimit, hideLabels, dumps = [], reportMode, resultsDir, } = params;
|
|
241
244
|
const cwd = await realpath(configuredCwd ?? process.cwd());
|
|
242
245
|
const dumpFiles = dumps.length ? await findFilesByGlobs(cwd, dumps) : [];
|
|
243
|
-
const shouldReadResults = resultsDir.length > 0 || dumps.length === 0;
|
|
244
|
-
const { resultDirectories = [], patterns = resultsDir } = shouldReadResults
|
|
245
|
-
? await findAllureResultDirectories(cwd, resultsDir)
|
|
246
|
-
: {};
|
|
247
246
|
if (dumps.length > 0 && dumpFiles.length === 0) {
|
|
248
247
|
throw new AgentUsageError(`No dump files found matching pattern: ${dumps.join(", ")}`);
|
|
249
248
|
}
|
|
249
|
+
const resultsConfig = await readConfig(cwd, configPath);
|
|
250
|
+
const resolvedPatterns = resolveResultsPatterns(resultsDir, resultsConfig.resultsDir);
|
|
251
|
+
const shouldReadResults = resolvedPatterns.length > 0 || dumpFiles.length === 0;
|
|
252
|
+
const { resultDirectories = [], patterns = resolvedPatterns } = shouldReadResults
|
|
253
|
+
? await resolveAndFindResultsDirs(cwd, resultsDir, resultsConfig.resultsDir)
|
|
254
|
+
: {};
|
|
250
255
|
if (resultDirectories.length === 0 && dumpFiles.length === 0) {
|
|
251
256
|
const inspectedPatterns = [...(patterns ?? []), ...dumps];
|
|
252
257
|
throw new AgentUsageError(`No test results directories or dump files found matching pattern: ${inspectedPatterns}`);
|
package/dist/commands/agent.d.ts
CHANGED
|
@@ -35,6 +35,7 @@ export declare class AgentCommand extends Command {
|
|
|
35
35
|
rerunPreset: string | undefined;
|
|
36
36
|
rerunEnvironments: string[] | undefined;
|
|
37
37
|
rerunLabels: string[] | undefined;
|
|
38
|
+
resultsDir: string[] | undefined;
|
|
38
39
|
commandToRun: string[];
|
|
39
40
|
execute(): Promise<void>;
|
|
40
41
|
}
|
package/dist/commands/agent.js
CHANGED
|
@@ -6,6 +6,7 @@ import { dirname, join, resolve } from "node:path";
|
|
|
6
6
|
import process, { exit } from "node:process";
|
|
7
7
|
import { AGENT_FINDING_CATEGORIES, AGENT_FINDING_SEVERITIES, AGENT_TASK_MAP_HELP, AGENT_TEST_STATUSES, AgentExpectationUsageError, assertExplicitAgentOutputDirIsSafe, buildAgentInlineExpectations, buildAgentQueryPayload, cleanupAgentRunState, cleanupStaleAgentRunStates, createAgentCapabilities, formatAgentOutputLinks, isAgentExpectationUsageError, isAgentTaskMapHelpRequest, isAgentUsageError, loadAgentOutput, normalizeAgentQueryLimit, normalizeAgentQueryView, normalizeAgentRerunPreset, normalizeRepeatedEnumValues, normalizeRepeatedStringValues, parseAgentLabelFilters, readLatestAgentState, resolveAgentSelectionOutputDir, resolveAgentStateDir, selectAgentTestPlan, validateAgentExpectationsFile, writeAgentRunState, writeInvalidAgentExpectationOutput, } from "@allurereport/plugin-agent";
|
|
8
8
|
import { Command, Option, UsageError } from "clipanion";
|
|
9
|
+
import { parseRunCommand } from "../utils/resultsPatterns.js";
|
|
9
10
|
export { AGENT_TASK_MAP_HELP, createAgentCapabilities, isAgentTaskMapHelpRequest };
|
|
10
11
|
const readOptionalString = (value) => (typeof value === "string" ? value : undefined);
|
|
11
12
|
const readOptionalBoolean = (value) => value === true;
|
|
@@ -125,7 +126,7 @@ export class AgentCommand extends Command {
|
|
|
125
126
|
constructor() {
|
|
126
127
|
super(...arguments);
|
|
127
128
|
this.config = Option.String("--config,-c", {
|
|
128
|
-
description: "The path Allure config file",
|
|
129
|
+
description: "The path to Allure config file",
|
|
129
130
|
});
|
|
130
131
|
this.cwd = Option.String("--cwd", {
|
|
131
132
|
description: "The working directory for the command to run (default: current working directory)",
|
|
@@ -195,18 +196,22 @@ export class AgentCommand extends Command {
|
|
|
195
196
|
this.rerunLabels = Option.Array("--rerun-label", {
|
|
196
197
|
description: "Filter rerun selection by exact label name=value. Repeat the option for multiple filters",
|
|
197
198
|
});
|
|
199
|
+
this.resultsDir = Option.Array("--results-dir", {
|
|
200
|
+
description: "Glob pattern or path for Allure results directories (repeatable). Overrides config.resultsDir. Quote globs in the shell",
|
|
201
|
+
});
|
|
198
202
|
this.commandToRun = Option.Rest();
|
|
199
203
|
}
|
|
200
204
|
async execute() {
|
|
201
|
-
const
|
|
205
|
+
const { command, commandArgs } = parseRunCommand(this.commandToRun);
|
|
206
|
+
if (!command) {
|
|
207
|
+
throw new UsageError("expecting command to be specified after --, e.g. allure agent -- npm run test");
|
|
208
|
+
}
|
|
209
|
+
const args = [command, ...commandArgs];
|
|
202
210
|
const configPath = readOptionalString(this.config);
|
|
203
211
|
const configuredCwd = readOptionalString(this.cwd);
|
|
204
212
|
const output = readOptionalString(this.output);
|
|
205
213
|
const reportMode = normalizeAgentHumanReportMode(readOptionalString(this.report));
|
|
206
214
|
const expectations = readOptionalString(this.expectations);
|
|
207
|
-
if (!args.length) {
|
|
208
|
-
throw new UsageError("expecting command to be specified after --, e.g. allure agent -- npm run test");
|
|
209
|
-
}
|
|
210
215
|
try {
|
|
211
216
|
if (output) {
|
|
212
217
|
await assertExplicitAgentOutputDirIsSafe(resolve(await realpath(configuredCwd ?? process.cwd()), output));
|
|
@@ -250,6 +255,7 @@ export class AgentCommand extends Command {
|
|
|
250
255
|
rerunLabels: readOptionalStringArray(this.rerunLabels),
|
|
251
256
|
reportMode,
|
|
252
257
|
args,
|
|
258
|
+
resultsPatterns: this.resultsDir ?? [],
|
|
253
259
|
});
|
|
254
260
|
}
|
|
255
261
|
catch (error) {
|
|
@@ -291,7 +297,8 @@ export class AgentCommand extends Command {
|
|
|
291
297
|
AgentCommand.paths = [["agent"]];
|
|
292
298
|
AgentCommand.usage = Command.Usage({
|
|
293
299
|
description: "Run specified command in Allure agent mode",
|
|
294
|
-
details: "This command runs the specified command with an agent-mode Allure profile and optional human-readable report output. With the default --report auto mode, runs with 1000 or fewer stored visible logical results also write a single-file Awesome report at <output>/awesome/index.html and record its status in <output>/manifest/human-report.json. If a user asks for the report after a run, use `allure agent latest` to recover the output directory and check the human-report manifest before regenerating anything."
|
|
300
|
+
details: "This command runs the specified command with an agent-mode Allure profile and optional human-readable report output. With the default --report auto mode, runs with 1000 or fewer stored visible logical results also write a single-file Awesome report at <output>/awesome/index.html and record its status in <output>/manifest/human-report.json. If a user asks for the report after a run, use `allure agent latest` to recover the output directory and check the human-report manifest before regenerating anything. " +
|
|
301
|
+
"Override results discovery with repeated `--results-dir` (CLI overrides `config.resultsDir`). Quote globs in the shell. When neither is set, directories named `allure-results` are discovered dynamically.",
|
|
295
302
|
examples: [
|
|
296
303
|
["agent -- npm test", "Run npm test and capture agent-mode output with the default human report policy"],
|
|
297
304
|
["agent --report off -- npm test", "Run npm test and capture only the agent-mode artifacts"],
|
|
@@ -299,16 +306,20 @@ AgentCommand.usage = Command.Usage({
|
|
|
299
306
|
"agent --expectations ./expected.yaml -- npm test",
|
|
300
307
|
"Run npm test with agent-mode expectations loaded from ./expected.yaml",
|
|
301
308
|
],
|
|
309
|
+
[
|
|
310
|
+
"agent --results-dir './artifacts/**/allure-results' -- npm test",
|
|
311
|
+
"Override results discovery with a quoted glob",
|
|
312
|
+
],
|
|
302
313
|
],
|
|
303
314
|
});
|
|
304
315
|
export class AgentInspectCommand extends Command {
|
|
305
316
|
constructor() {
|
|
306
317
|
super(...arguments);
|
|
307
318
|
this.resultsDir = Option.Rest({
|
|
308
|
-
name: "Patterns to match test results directories
|
|
319
|
+
name: "Patterns to match test results directories. Overrides config.resultsDir. Defaults to ./**/allure-results when neither is set.",
|
|
309
320
|
});
|
|
310
321
|
this.config = Option.String("--config,-c", {
|
|
311
|
-
description: "The path Allure config file",
|
|
322
|
+
description: "The path to Allure config file",
|
|
312
323
|
});
|
|
313
324
|
this.cwd = Option.String("--cwd", {
|
|
314
325
|
description: "The working directory for resolving results and dumps (default: current working directory)",
|
package/dist/commands/allure2.js
CHANGED
|
@@ -5,15 +5,15 @@ import { AllureReport, readConfig } from "@allurereport/core";
|
|
|
5
5
|
import Allure2Plugin from "@allurereport/plugin-allure2";
|
|
6
6
|
import { Command, Option } from "clipanion";
|
|
7
7
|
import { red } from "yoctocolors";
|
|
8
|
-
import {
|
|
8
|
+
import { resolveAndFindResultsDirs } from "../utils/resultsPatterns.js";
|
|
9
9
|
export class Allure2Command extends Command {
|
|
10
10
|
constructor() {
|
|
11
11
|
super(...arguments);
|
|
12
12
|
this.resultsDir = Option.Rest({
|
|
13
|
-
name: "Patterns to match test results directories
|
|
13
|
+
name: "Patterns to match test results directories. Overrides config.resultsDir. Defaults to ./**/allure-results when neither is set.",
|
|
14
14
|
});
|
|
15
15
|
this.config = Option.String("--config,-c", {
|
|
16
|
-
description: "The path Allure config file",
|
|
16
|
+
description: "The path to Allure config file",
|
|
17
17
|
});
|
|
18
18
|
this.cwd = Option.String("--cwd", {
|
|
19
19
|
description: "The working directory for the command to run (default: current working directory)",
|
|
@@ -39,12 +39,6 @@ export class Allure2Command extends Command {
|
|
|
39
39
|
}
|
|
40
40
|
async execute() {
|
|
41
41
|
const cwd = await realpath(this.cwd ?? process.cwd());
|
|
42
|
-
const { resultDirectories, patterns } = await findAllureResultDirectories(cwd, this.resultsDir);
|
|
43
|
-
if (!resultDirectories.length) {
|
|
44
|
-
console.error(red(`No test results directories found matching pattern: ${patterns}`));
|
|
45
|
-
exit(1);
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
42
|
const before = new Date().getTime();
|
|
49
43
|
const defaultAllure2Options = {
|
|
50
44
|
singleFile: this.singleFile ?? false,
|
|
@@ -56,6 +50,12 @@ export class Allure2Command extends Command {
|
|
|
56
50
|
knownIssuesPath: this.knownIssues,
|
|
57
51
|
historyPath: this.historyPath,
|
|
58
52
|
});
|
|
53
|
+
const { resultDirectories, patterns } = await resolveAndFindResultsDirs(cwd, this.resultsDir, config.resultsDir);
|
|
54
|
+
if (!resultDirectories.length) {
|
|
55
|
+
console.error(red(`No test results directories found matching pattern: ${patterns}`));
|
|
56
|
+
exit(1);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
59
|
config.plugins = [
|
|
60
60
|
{
|
|
61
61
|
id: "allure2",
|
package/dist/commands/awesome.js
CHANGED
|
@@ -5,15 +5,15 @@ import { AllureReport, readConfig } from "@allurereport/core";
|
|
|
5
5
|
import { default as AwesomePlugin } from "@allurereport/plugin-awesome";
|
|
6
6
|
import { Command, Option } from "clipanion";
|
|
7
7
|
import { red } from "yoctocolors";
|
|
8
|
-
import {
|
|
8
|
+
import { resolveAndFindResultsDirs } from "../utils/resultsPatterns.js";
|
|
9
9
|
export class AwesomeCommand extends Command {
|
|
10
10
|
constructor() {
|
|
11
11
|
super(...arguments);
|
|
12
12
|
this.resultsDir = Option.Rest({
|
|
13
|
-
name: "Patterns to match test results directories
|
|
13
|
+
name: "Patterns to match test results directories. Overrides config.resultsDir. Defaults to ./**/allure-results when neither is set.",
|
|
14
14
|
});
|
|
15
15
|
this.config = Option.String("--config,-c", {
|
|
16
|
-
description: "The path Allure config file",
|
|
16
|
+
description: "The path to Allure config file",
|
|
17
17
|
});
|
|
18
18
|
this.cwd = Option.String("--cwd", {
|
|
19
19
|
description: "The working directory for the command to run (default: current working directory)",
|
|
@@ -51,12 +51,6 @@ export class AwesomeCommand extends Command {
|
|
|
51
51
|
}
|
|
52
52
|
async execute() {
|
|
53
53
|
const cwd = await realpath(this.cwd ?? process.cwd());
|
|
54
|
-
const { resultDirectories, patterns } = await findAllureResultDirectories(cwd, this.resultsDir);
|
|
55
|
-
if (!resultDirectories.length) {
|
|
56
|
-
console.error(red(`No test results directories found matching pattern: ${patterns}`));
|
|
57
|
-
exit(1);
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
54
|
const before = new Date().getTime();
|
|
61
55
|
const hideLabels = this.hideLabels?.length ? this.hideLabels : undefined;
|
|
62
56
|
const config = await readConfig(cwd, this.config, {
|
|
@@ -66,6 +60,12 @@ export class AwesomeCommand extends Command {
|
|
|
66
60
|
historyPath: this.historyPath,
|
|
67
61
|
hideLabels,
|
|
68
62
|
});
|
|
63
|
+
const { resultDirectories, patterns } = await resolveAndFindResultsDirs(cwd, this.resultsDir, config.resultsDir);
|
|
64
|
+
if (!resultDirectories.length) {
|
|
65
|
+
console.error(red(`No test results directories found matching pattern: ${patterns}`));
|
|
66
|
+
exit(1);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
69
|
const defaultAwesomeOptions = {
|
|
70
70
|
singleFile: this.singleFile ?? false,
|
|
71
71
|
logo: this.logo,
|
package/dist/commands/check.js
CHANGED
|
@@ -95,7 +95,7 @@ export class CheckCommand extends Command {
|
|
|
95
95
|
description: "Add a tag to the check result. Repeat the option for multiple tags",
|
|
96
96
|
});
|
|
97
97
|
this.config = Option.String("--config,-c", {
|
|
98
|
-
description: "The path Allure config file",
|
|
98
|
+
description: "The path to Allure config file",
|
|
99
99
|
});
|
|
100
100
|
this.cwd = Option.String("--cwd", {
|
|
101
101
|
description: "The working directory for the command to run (default: current working directory)",
|
package/dist/commands/classic.js
CHANGED
|
@@ -5,15 +5,15 @@ import { AllureReport, readConfig } from "@allurereport/core";
|
|
|
5
5
|
import ClassicPlugin from "@allurereport/plugin-classic";
|
|
6
6
|
import { Command, Option } from "clipanion";
|
|
7
7
|
import { red } from "yoctocolors";
|
|
8
|
-
import {
|
|
8
|
+
import { resolveAndFindResultsDirs } from "../utils/resultsPatterns.js";
|
|
9
9
|
export class ClassicCommand extends Command {
|
|
10
10
|
constructor() {
|
|
11
11
|
super(...arguments);
|
|
12
12
|
this.resultsDir = Option.Rest({
|
|
13
|
-
name: "Patterns to match test results directories
|
|
13
|
+
name: "Patterns to match test results directories. Overrides config.resultsDir. Defaults to ./**/allure-results when neither is set.",
|
|
14
14
|
});
|
|
15
15
|
this.config = Option.String("--config,-c", {
|
|
16
|
-
description: "The path Allure config file",
|
|
16
|
+
description: "The path to Allure config file",
|
|
17
17
|
});
|
|
18
18
|
this.cwd = Option.String("--cwd", {
|
|
19
19
|
description: "The working directory for the command to run (default: current working directory)",
|
|
@@ -39,12 +39,6 @@ export class ClassicCommand extends Command {
|
|
|
39
39
|
}
|
|
40
40
|
async execute() {
|
|
41
41
|
const cwd = await realpath(this.cwd ?? process.cwd());
|
|
42
|
-
const { resultDirectories, patterns } = await findAllureResultDirectories(cwd, this.resultsDir);
|
|
43
|
-
if (!resultDirectories.length) {
|
|
44
|
-
console.error(red(`No test results directories found matching pattern: ${patterns}`));
|
|
45
|
-
exit(1);
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
42
|
const before = new Date().getTime();
|
|
49
43
|
const defaultClassicOptions = {
|
|
50
44
|
singleFile: this.singleFile ?? false,
|
|
@@ -56,6 +50,12 @@ export class ClassicCommand extends Command {
|
|
|
56
50
|
knownIssuesPath: this.knownIssues,
|
|
57
51
|
historyPath: this.historyPath,
|
|
58
52
|
});
|
|
53
|
+
const { resultDirectories, patterns } = await resolveAndFindResultsDirs(cwd, this.resultsDir, config.resultsDir);
|
|
54
|
+
if (!resultDirectories.length) {
|
|
55
|
+
console.error(red(`No test results directories found matching pattern: ${patterns}`));
|
|
56
|
+
exit(1);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
59
|
config.plugins = [
|
|
60
60
|
{
|
|
61
61
|
id: "classic",
|
|
@@ -2,12 +2,16 @@ import { exit } from "node:process";
|
|
|
2
2
|
import { AllureReport } from "@allurereport/core";
|
|
3
3
|
import { KnownError } from "@allurereport/service";
|
|
4
4
|
import { red } from "yoctocolors";
|
|
5
|
-
import {
|
|
5
|
+
import { findFilesByGlobs } from "../../utils/fileSystem.js";
|
|
6
6
|
import { logError } from "../../utils/logs.js";
|
|
7
|
+
import { resolveAndFindResultsDirs, resolveResultsPatterns } from "../../utils/resultsPatterns.js";
|
|
7
8
|
export const generate = async (params) => {
|
|
8
9
|
const dumpFiles = params?.dump?.length ? await findFilesByGlobs(params.cwd, params.dump) : [];
|
|
9
|
-
const
|
|
10
|
-
|
|
10
|
+
const cliPatterns = params.resultsDir ?? [];
|
|
11
|
+
const resolvedPatterns = resolveResultsPatterns(cliPatterns, params.config.resultsDir);
|
|
12
|
+
const shouldReadResults = resolvedPatterns.length > 0 || dumpFiles.length === 0;
|
|
13
|
+
const { resultDirectories = [], patterns = resolvedPatterns } = shouldReadResults
|
|
14
|
+
? await resolveAndFindResultsDirs(params.cwd, cliPatterns, params.config.resultsDir)
|
|
11
15
|
: {};
|
|
12
16
|
if (resultDirectories.length === 0 && dumpFiles.length === 0) {
|
|
13
17
|
console.error(red(`No test results directories found matching pattern: ${patterns}`));
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Watcher } from "@allurereport/directory-watcher";
|
|
2
|
+
export declare const allureResultsDirectoriesGlobWatcher: (cwd: string, patterns: readonly string[], update: (newAllureResults: Set<string>, deletedAllureResults: Set<string>) => Promise<void>, options?: {
|
|
3
|
+
indexDelay?: number;
|
|
4
|
+
abortController?: AbortController;
|
|
5
|
+
}) => Watcher;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { difference, watch } from "@allurereport/directory-watcher";
|
|
2
|
+
import { findDirectoriesByGlobs } from "../../utils/fileSystem.js";
|
|
3
|
+
export const allureResultsDirectoriesGlobWatcher = (cwd, patterns, update, options = {}) => {
|
|
4
|
+
const { abortController = new AbortController(), indexDelay = 600 } = options;
|
|
5
|
+
let previousAllureResults = new Set();
|
|
6
|
+
const callback = async () => {
|
|
7
|
+
if (abortController.signal.aborted) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
const matched = await findDirectoriesByGlobs(cwd, patterns);
|
|
11
|
+
const currentAllureResults = new Set(matched);
|
|
12
|
+
const [added, deleted] = difference(previousAllureResults, currentAllureResults);
|
|
13
|
+
await update(added, deleted);
|
|
14
|
+
previousAllureResults = currentAllureResults;
|
|
15
|
+
};
|
|
16
|
+
return watch(callback, callback, callback, { indexDelay, abortController });
|
|
17
|
+
};
|
|
@@ -28,6 +28,7 @@ export declare const runTests: (params: {
|
|
|
28
28
|
silent?: boolean;
|
|
29
29
|
logs?: RunLogsMode;
|
|
30
30
|
logProcessExit?: boolean;
|
|
31
|
+
resultsPatterns?: readonly string[];
|
|
31
32
|
}) => Promise<TestProcessResult | null>;
|
|
32
33
|
export declare const executeAllureRun: (params: {
|
|
33
34
|
allureReport: AllureReport;
|
|
@@ -43,6 +44,7 @@ export declare const executeAllureRun: (params: {
|
|
|
43
44
|
ignoreLogs?: boolean;
|
|
44
45
|
maxRerun?: number;
|
|
45
46
|
logProcessExit?: boolean;
|
|
47
|
+
resultsPatterns?: readonly string[];
|
|
46
48
|
}) => Promise<{
|
|
47
49
|
globalExitCode: ExitCode;
|
|
48
50
|
testProcessResult: TestProcessResult | null;
|
|
@@ -14,6 +14,7 @@ import { red } from "yoctocolors";
|
|
|
14
14
|
import { logTests, runProcess, terminationOf } from "../../utils/index.js";
|
|
15
15
|
import { logError } from "../../utils/logs.js";
|
|
16
16
|
import { stopProcessTree } from "../../utils/process.js";
|
|
17
|
+
import { allureResultsDirectoriesGlobWatcher } from "./resultsDiscovery.js";
|
|
17
18
|
export const executeNestedAllureCommand = async (params) => {
|
|
18
19
|
const nestedProcess = runProcess({
|
|
19
20
|
command: params.command,
|
|
@@ -24,8 +25,16 @@ export const executeNestedAllureCommand = async (params) => {
|
|
|
24
25
|
});
|
|
25
26
|
return await terminationOf(nestedProcess);
|
|
26
27
|
};
|
|
28
|
+
const attachResultsDirectoryWatchers = (params) => {
|
|
29
|
+
if (params.resultsPatterns.length > 0) {
|
|
30
|
+
return allureResultsDirectoriesGlobWatcher(params.cwd, params.resultsPatterns, params.onUpdate, {
|
|
31
|
+
indexDelay: 600,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
return allureResultsDirectoriesWatcher(params.cwd, params.onUpdate, { indexDelay: 600 });
|
|
35
|
+
};
|
|
27
36
|
export const runTests = async (params) => {
|
|
28
|
-
const { allureReport, knownIssues, cwd, command, commandArgs, logs, environmentVariables, environment, withQualityGate, silent, logProcessExit = true, } = params;
|
|
37
|
+
const { allureReport, knownIssues, cwd, command, commandArgs, logs, environmentVariables, environment, withQualityGate, silent, logProcessExit = true, resultsPatterns = [], } = params;
|
|
29
38
|
let testProcessStarted = false;
|
|
30
39
|
const allureResultsWatchers = new Map();
|
|
31
40
|
const processWatcher = delayedFileProcessingWatcher(async (path) => {
|
|
@@ -34,28 +43,32 @@ export const runTests = async (params) => {
|
|
|
34
43
|
indexDelay: 200,
|
|
35
44
|
minProcessingDelay: 1000,
|
|
36
45
|
});
|
|
37
|
-
const allureResultsWatch =
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
46
|
+
const allureResultsWatch = attachResultsDirectoryWatchers({
|
|
47
|
+
cwd,
|
|
48
|
+
resultsPatterns,
|
|
49
|
+
onUpdate: async (newAllureResults, deletedAllureResults) => {
|
|
50
|
+
for (const delAr of deletedAllureResults) {
|
|
51
|
+
const watcher = allureResultsWatchers.get(delAr);
|
|
52
|
+
if (watcher) {
|
|
53
|
+
await watcher.abort();
|
|
54
|
+
}
|
|
55
|
+
allureResultsWatchers.delete(delAr);
|
|
42
56
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
57
|
+
for (const newAr of newAllureResults) {
|
|
58
|
+
if (allureResultsWatchers.has(newAr)) {
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
const watcher = newFilesInDirectoryWatcher(newAr, async (path) => {
|
|
62
|
+
await processWatcher.addFile(path);
|
|
63
|
+
}, {
|
|
64
|
+
ignoreInitial: !testProcessStarted,
|
|
65
|
+
indexDelay: 300,
|
|
66
|
+
});
|
|
67
|
+
allureResultsWatchers.set(newAr, watcher);
|
|
68
|
+
await watcher.initialScan();
|
|
48
69
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}, {
|
|
52
|
-
ignoreInitial: !testProcessStarted,
|
|
53
|
-
indexDelay: 300,
|
|
54
|
-
});
|
|
55
|
-
allureResultsWatchers.set(newAr, watcher);
|
|
56
|
-
await watcher.initialScan();
|
|
57
|
-
}
|
|
58
|
-
}, { indexDelay: 600 });
|
|
70
|
+
},
|
|
71
|
+
});
|
|
59
72
|
await allureResultsWatch.initialScan();
|
|
60
73
|
testProcessStarted = true;
|
|
61
74
|
const beforeProcess = Date.now();
|
|
@@ -148,7 +161,7 @@ export const runTests = async (params) => {
|
|
|
148
161
|
};
|
|
149
162
|
};
|
|
150
163
|
export const executeAllureRun = async (params) => {
|
|
151
|
-
const { allureReport, knownIssues, cwd, command, commandArgs, environmentVariables = {}, environment, withQualityGate, silent, logs, ignoreLogs, maxRerun = 0, logProcessExit = true, } = params;
|
|
164
|
+
const { allureReport, knownIssues, cwd, command, commandArgs, environmentVariables = {}, environment, withQualityGate, silent, logs, ignoreLogs, maxRerun = 0, logProcessExit = true, resultsPatterns = [], } = params;
|
|
152
165
|
await allureReport.start();
|
|
153
166
|
const globalExitCode = {
|
|
154
167
|
original: 0,
|
|
@@ -169,6 +182,7 @@ export const executeAllureRun = async (params) => {
|
|
|
169
182
|
environmentVariables,
|
|
170
183
|
withQualityGate,
|
|
171
184
|
logProcessExit,
|
|
185
|
+
resultsPatterns,
|
|
172
186
|
});
|
|
173
187
|
const allFailuresAfterInitialRun = await allureReport.store.failedTestResults();
|
|
174
188
|
const blockingFailuresAfterInitialRun = await allureReport.store.blockingFailedTestResults();
|
|
@@ -203,6 +217,7 @@ export const executeAllureRun = async (params) => {
|
|
|
203
217
|
},
|
|
204
218
|
withQualityGate,
|
|
205
219
|
logProcessExit,
|
|
220
|
+
resultsPatterns,
|
|
206
221
|
});
|
|
207
222
|
await rm(tmpDir, { recursive: true });
|
|
208
223
|
logTests(await allureReport.store.allTestResults());
|
package/dist/commands/csv.js
CHANGED
|
@@ -6,15 +6,15 @@ import { AllureReport, readConfig } from "@allurereport/core";
|
|
|
6
6
|
import CsvPlugin from "@allurereport/plugin-csv";
|
|
7
7
|
import { Command, Option } from "clipanion";
|
|
8
8
|
import { red } from "yoctocolors";
|
|
9
|
-
import {
|
|
9
|
+
import { resolveAndFindResultsDirs } from "../utils/resultsPatterns.js";
|
|
10
10
|
export class CsvCommand extends Command {
|
|
11
11
|
constructor() {
|
|
12
12
|
super(...arguments);
|
|
13
13
|
this.resultsDir = Option.Rest({
|
|
14
|
-
name: "Patterns to match test results directories
|
|
14
|
+
name: "Patterns to match test results directories. Overrides config.resultsDir. Defaults to ./**/allure-results when neither is set.",
|
|
15
15
|
});
|
|
16
16
|
this.config = Option.String("--config,-c", {
|
|
17
|
-
description: "The path Allure config file",
|
|
17
|
+
description: "The path to Allure config file",
|
|
18
18
|
});
|
|
19
19
|
this.cwd = Option.String("--cwd", {
|
|
20
20
|
description: "The working directory for the command to run (default: current working directory)",
|
|
@@ -34,12 +34,6 @@ export class CsvCommand extends Command {
|
|
|
34
34
|
}
|
|
35
35
|
async execute() {
|
|
36
36
|
const cwd = await realpath(this.cwd ?? process.cwd());
|
|
37
|
-
const { resultDirectories, patterns } = await findAllureResultDirectories(cwd, this.resultsDir);
|
|
38
|
-
if (!resultDirectories.length) {
|
|
39
|
-
console.error(red(`No test results directories found matching pattern: ${patterns}`));
|
|
40
|
-
exit(1);
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
37
|
const before = new Date().getTime();
|
|
44
38
|
const defaultCsvOptions = {
|
|
45
39
|
separator: this.separator ?? ",",
|
|
@@ -49,6 +43,12 @@ export class CsvCommand extends Command {
|
|
|
49
43
|
const config = await readConfig(cwd, this.config, {
|
|
50
44
|
knownIssuesPath: this.knownIssues,
|
|
51
45
|
});
|
|
46
|
+
const { resultDirectories, patterns } = await resolveAndFindResultsDirs(cwd, this.resultsDir, config.resultsDir);
|
|
47
|
+
if (!resultDirectories.length) {
|
|
48
|
+
console.error(red(`No test results directories found matching pattern: ${patterns}`));
|
|
49
|
+
exit(1);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
52
|
config.plugins = [
|
|
53
53
|
{
|
|
54
54
|
id: "csv",
|
|
@@ -5,15 +5,15 @@ import { AllureReport, readConfig } from "@allurereport/core";
|
|
|
5
5
|
import DashboardPlugin from "@allurereport/plugin-dashboard";
|
|
6
6
|
import { Command, Option } from "clipanion";
|
|
7
7
|
import { red } from "yoctocolors";
|
|
8
|
-
import {
|
|
8
|
+
import { resolveAndFindResultsDirs } from "../utils/resultsPatterns.js";
|
|
9
9
|
export class DashboardCommand extends Command {
|
|
10
10
|
constructor() {
|
|
11
11
|
super(...arguments);
|
|
12
12
|
this.resultsDir = Option.Rest({
|
|
13
|
-
name: "Patterns to match test results directories
|
|
13
|
+
name: "Patterns to match test results directories. Overrides config.resultsDir. Defaults to ./**/allure-results when neither is set.",
|
|
14
14
|
});
|
|
15
15
|
this.config = Option.String("--config,-c", {
|
|
16
|
-
description: "The path Allure config file",
|
|
16
|
+
description: "The path to Allure config file",
|
|
17
17
|
});
|
|
18
18
|
this.cwd = Option.String("--cwd", {
|
|
19
19
|
description: "The working directory for the command to run (default: current working directory)",
|
|
@@ -39,12 +39,6 @@ export class DashboardCommand extends Command {
|
|
|
39
39
|
}
|
|
40
40
|
async execute() {
|
|
41
41
|
const cwd = await realpath(this.cwd ?? process.cwd());
|
|
42
|
-
const { resultDirectories, patterns } = await findAllureResultDirectories(cwd, this.resultsDir);
|
|
43
|
-
if (!resultDirectories.length) {
|
|
44
|
-
console.error(red(`No test results directories found matching pattern: ${patterns}`));
|
|
45
|
-
exit(1);
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
42
|
const before = new Date().getTime();
|
|
49
43
|
const defaultDashboardOptions = {
|
|
50
44
|
singleFile: this.singleFile ?? false,
|
|
@@ -56,6 +50,12 @@ export class DashboardCommand extends Command {
|
|
|
56
50
|
output: this.output,
|
|
57
51
|
name: this.reportName,
|
|
58
52
|
});
|
|
53
|
+
const { resultDirectories, patterns } = await resolveAndFindResultsDirs(cwd, this.resultsDir, config.resultsDir);
|
|
54
|
+
if (!resultDirectories.length) {
|
|
55
|
+
console.error(red(`No test results directories found matching pattern: ${patterns}`));
|
|
56
|
+
exit(1);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
59
|
config.plugins = [
|
|
60
60
|
{
|
|
61
61
|
id: "dashboard",
|
|
@@ -7,10 +7,10 @@ export class GenerateCommand extends Command {
|
|
|
7
7
|
constructor() {
|
|
8
8
|
super(...arguments);
|
|
9
9
|
this.resultsDir = Option.Rest({
|
|
10
|
-
name: "Patterns to match test results directories
|
|
10
|
+
name: "Patterns to match test results directories. Overrides config.resultsDir. Defaults to ./**/allure-results when neither is set.",
|
|
11
11
|
});
|
|
12
12
|
this.config = Option.String("--config,-c", {
|
|
13
|
-
description: "The path Allure config file",
|
|
13
|
+
description: "The path to Allure config file",
|
|
14
14
|
});
|
|
15
15
|
this.output = Option.String("--output,-o", {
|
|
16
16
|
description: "The output directory name. Absolute paths are accepted as well (default: allure-report)",
|