allure 3.5.0 → 3.6.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 +17 -0
- package/dist/commands/agent.d.ts +58 -0
- package/dist/commands/agent.js +374 -0
- package/dist/commands/commons/run.d.ts +48 -0
- package/dist/commands/commons/run.js +258 -0
- package/dist/commands/index.d.ts +1 -0
- package/dist/commands/index.js +1 -0
- package/dist/commands/run.d.ts +0 -7
- package/dist/commands/run.js +51 -238
- package/dist/index.js +5 -1
- package/dist/utils/agent-select.d.ts +41 -0
- package/dist/utils/agent-select.js +141 -0
- package/dist/utils/agent-state.d.ts +15 -0
- package/dist/utils/agent-state.js +83 -0
- package/dist/utils/environment.d.ts +7 -2
- package/dist/utils/environment.js +1 -1
- package/dist/utils/execution-context.d.ts +4 -0
- package/dist/utils/execution-context.js +9 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.js +3 -0
- package/dist/utils/process.js +2 -1
- package/package.json +21 -20
package/README.md
CHANGED
|
@@ -60,6 +60,22 @@ To successfully generate a report, ensure that your test setup outputs results i
|
|
|
60
60
|
|
|
61
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.
|
|
62
62
|
|
|
63
|
+
### Running Tests In Agent Mode
|
|
64
|
+
|
|
65
|
+
When you need agent-friendly markdown output for review, debugging, or scope validation, use the `agent` command:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
npx allure agent -- <test_command>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
For example:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
npx allure agent -- npm test
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
`allure agent` runs with an agent-only profile by default. It creates a fresh output directory automatically, can load an expectations file with `--expectations`, and ignores configured presentation or export plugins such as Awesome or TestOps unless you explicitly fall back to the lower-level `ALLURE_AGENT_*` plus `allure run` flow.
|
|
78
|
+
|
|
63
79
|
### Generating Reports Manually
|
|
64
80
|
|
|
65
81
|
If you already have test results and wish to generate a report manually, use the `generate` command:
|
|
@@ -102,6 +118,7 @@ The Allure CLI includes several helpful global options. Use `--help` to explore
|
|
|
102
118
|
|
|
103
119
|
```bash
|
|
104
120
|
npx allure run --help
|
|
121
|
+
npx allure agent --help
|
|
105
122
|
npx allure watch --help
|
|
106
123
|
```
|
|
107
124
|
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Command } from "clipanion";
|
|
2
|
+
export declare class AgentCommand extends Command {
|
|
3
|
+
static paths: string[][];
|
|
4
|
+
static usage: import("clipanion").Usage;
|
|
5
|
+
config: string | undefined;
|
|
6
|
+
cwd: string | undefined;
|
|
7
|
+
output: string | undefined;
|
|
8
|
+
expectations: string | undefined;
|
|
9
|
+
environment: string | undefined;
|
|
10
|
+
environmentName: string | undefined;
|
|
11
|
+
silent: boolean | undefined;
|
|
12
|
+
rerunFrom: string | undefined;
|
|
13
|
+
rerunLatest: boolean | undefined;
|
|
14
|
+
rerunPreset: string | undefined;
|
|
15
|
+
rerunEnvironments: string[] | undefined;
|
|
16
|
+
rerunLabels: string[] | undefined;
|
|
17
|
+
commandToRun: string[];
|
|
18
|
+
execute(): Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
export declare class AgentLatestCommand extends Command {
|
|
21
|
+
static paths: string[][];
|
|
22
|
+
static usage: import("clipanion").Usage;
|
|
23
|
+
cwd: string | undefined;
|
|
24
|
+
execute(): Promise<void>;
|
|
25
|
+
}
|
|
26
|
+
export declare class AgentStateDirCommand extends Command {
|
|
27
|
+
static paths: string[][];
|
|
28
|
+
static usage: import("clipanion").Usage;
|
|
29
|
+
cwd: string | undefined;
|
|
30
|
+
execute(): Promise<void>;
|
|
31
|
+
}
|
|
32
|
+
export declare class AgentSelectCommand extends Command {
|
|
33
|
+
static paths: string[][];
|
|
34
|
+
static usage: import("clipanion").Usage;
|
|
35
|
+
cwd: string | undefined;
|
|
36
|
+
from: string | undefined;
|
|
37
|
+
latest: boolean | undefined;
|
|
38
|
+
preset: string | undefined;
|
|
39
|
+
environments: string[] | undefined;
|
|
40
|
+
labels: string[] | undefined;
|
|
41
|
+
output: string | undefined;
|
|
42
|
+
execute(): Promise<void>;
|
|
43
|
+
}
|
|
44
|
+
export declare const executeAgentMode: (params: {
|
|
45
|
+
configPath?: string;
|
|
46
|
+
cwd?: string;
|
|
47
|
+
output?: string;
|
|
48
|
+
expectations?: string;
|
|
49
|
+
environment?: string;
|
|
50
|
+
environmentName?: string;
|
|
51
|
+
silent?: boolean;
|
|
52
|
+
rerunFrom?: string;
|
|
53
|
+
rerunLatest?: boolean;
|
|
54
|
+
rerunPreset?: string;
|
|
55
|
+
rerunEnvironments?: string[];
|
|
56
|
+
rerunLabels?: string[];
|
|
57
|
+
args?: string[];
|
|
58
|
+
}) => Promise<void>;
|
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
import * as console from "node:console";
|
|
2
|
+
import { mkdir, mkdtemp, realpath, rm, writeFile } from "node:fs/promises";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { dirname, join, relative, resolve } from "node:path";
|
|
5
|
+
import process, { exit } from "node:process";
|
|
6
|
+
import { AllureReport, isFileNotFoundError, readConfig } from "@allurereport/core";
|
|
7
|
+
import { Command, Option, UsageError } from "clipanion";
|
|
8
|
+
import { createAgentTestPlanContext, normalizeAgentRerunPreset, parseAgentLabelFilters, resolveAgentSelectionOutputDir, selectAgentTestPlan, } from "../utils/agent-select.js";
|
|
9
|
+
import { readLatestAgentState, resolveAgentStateDir, writeLatestAgentState } from "../utils/agent-state.js";
|
|
10
|
+
import { environmentNameOption, environmentOption, normalizeCommandEnvironmentOptions, resolveCommandEnvironment, } from "../utils/environment.js";
|
|
11
|
+
import { createChildAllureCliEnvironment, getActiveAllureCliCommand } from "../utils/execution-context.js";
|
|
12
|
+
import { executeAllureRun, executeNestedAllureCommand } from "./commons/run.js";
|
|
13
|
+
const withProcessEnv = async (overrides, fn) => {
|
|
14
|
+
const previousValues = new Map();
|
|
15
|
+
for (const [key, value] of Object.entries(overrides)) {
|
|
16
|
+
previousValues.set(key, process.env[key]);
|
|
17
|
+
if (value === undefined) {
|
|
18
|
+
delete process.env[key];
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
process.env[key] = value;
|
|
22
|
+
}
|
|
23
|
+
try {
|
|
24
|
+
return await fn();
|
|
25
|
+
}
|
|
26
|
+
finally {
|
|
27
|
+
for (const [key, value] of previousValues) {
|
|
28
|
+
if (value === undefined) {
|
|
29
|
+
delete process.env[key];
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
process.env[key] = value;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
const isPathInside = (parentPath, candidatePath) => {
|
|
37
|
+
const rel = relative(parentPath, candidatePath);
|
|
38
|
+
return rel === "" || (!rel.startsWith("..") && rel !== "." && !rel.startsWith("../"));
|
|
39
|
+
};
|
|
40
|
+
const persistLatestAgentState = async (value) => {
|
|
41
|
+
try {
|
|
42
|
+
await writeLatestAgentState(value);
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
console.error(`Could not update latest agent output in ${resolveAgentStateDir(value.cwd)}: ${error.message}`);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
const readOptionalString = (value) => (typeof value === "string" ? value : undefined);
|
|
49
|
+
const readOptionalBoolean = (value) => value === true;
|
|
50
|
+
const readOptionalStringArray = (value) => (Array.isArray(value) ? value : undefined);
|
|
51
|
+
export class AgentCommand extends Command {
|
|
52
|
+
constructor() {
|
|
53
|
+
super(...arguments);
|
|
54
|
+
this.config = Option.String("--config,-c", {
|
|
55
|
+
description: "The path Allure config file",
|
|
56
|
+
});
|
|
57
|
+
this.cwd = Option.String("--cwd", {
|
|
58
|
+
description: "The working directory for the command to run (default: current working directory)",
|
|
59
|
+
});
|
|
60
|
+
this.output = Option.String("--output,-o", {
|
|
61
|
+
description: "The output directory for agent artifacts. Absolute paths are accepted as well",
|
|
62
|
+
});
|
|
63
|
+
this.expectations = Option.String("--expectations", {
|
|
64
|
+
description: "The path to a YAML or JSON expectations file",
|
|
65
|
+
});
|
|
66
|
+
this.environment = environmentOption();
|
|
67
|
+
this.environmentName = environmentNameOption();
|
|
68
|
+
this.silent = Option.Boolean("--silent", {
|
|
69
|
+
description: "Don't pipe the process output logs to console (default: false)",
|
|
70
|
+
});
|
|
71
|
+
this.rerunFrom = Option.String("--rerun-from", {
|
|
72
|
+
description: "Select tests for rerun from an existing agent output directory",
|
|
73
|
+
});
|
|
74
|
+
this.rerunLatest = Option.Boolean("--rerun-latest", {
|
|
75
|
+
description: "Select tests for rerun from the latest recorded agent output for the current project",
|
|
76
|
+
});
|
|
77
|
+
this.rerunPreset = Option.String("--rerun-preset", {
|
|
78
|
+
description: "The rerun selection preset: review, failed, unsuccessful, or all (default: review)",
|
|
79
|
+
});
|
|
80
|
+
this.rerunEnvironments = Option.Array("--rerun-environment", {
|
|
81
|
+
description: "Filter rerun selection by environment id. Repeat the option for multiple environments",
|
|
82
|
+
});
|
|
83
|
+
this.rerunLabels = Option.Array("--rerun-label", {
|
|
84
|
+
description: "Filter rerun selection by exact label name=value. Repeat the option for multiple filters",
|
|
85
|
+
});
|
|
86
|
+
this.commandToRun = Option.Rest();
|
|
87
|
+
}
|
|
88
|
+
async execute() {
|
|
89
|
+
const args = this.commandToRun.filter((arg) => arg !== "--");
|
|
90
|
+
await executeAgentMode({
|
|
91
|
+
configPath: readOptionalString(this.config),
|
|
92
|
+
cwd: readOptionalString(this.cwd),
|
|
93
|
+
output: readOptionalString(this.output),
|
|
94
|
+
expectations: readOptionalString(this.expectations),
|
|
95
|
+
environment: readOptionalString(this.environment),
|
|
96
|
+
environmentName: readOptionalString(this.environmentName),
|
|
97
|
+
silent: readOptionalBoolean(this.silent),
|
|
98
|
+
rerunFrom: readOptionalString(this.rerunFrom),
|
|
99
|
+
rerunLatest: readOptionalBoolean(this.rerunLatest),
|
|
100
|
+
rerunPreset: readOptionalString(this.rerunPreset),
|
|
101
|
+
rerunEnvironments: readOptionalStringArray(this.rerunEnvironments),
|
|
102
|
+
rerunLabels: readOptionalStringArray(this.rerunLabels),
|
|
103
|
+
args,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
AgentCommand.paths = [["agent"]];
|
|
108
|
+
AgentCommand.usage = Command.Usage({
|
|
109
|
+
description: "Run specified command in Allure agent mode",
|
|
110
|
+
details: "This command runs the specified command with an agent-only Allure profile.",
|
|
111
|
+
examples: [
|
|
112
|
+
["agent -- npm test", "Run npm test and capture only the agent-mode output"],
|
|
113
|
+
[
|
|
114
|
+
"agent --expectations ./expected.yaml -- npm test",
|
|
115
|
+
"Run npm test with agent-mode expectations loaded from ./expected.yaml",
|
|
116
|
+
],
|
|
117
|
+
],
|
|
118
|
+
});
|
|
119
|
+
export class AgentLatestCommand extends Command {
|
|
120
|
+
constructor() {
|
|
121
|
+
super(...arguments);
|
|
122
|
+
this.cwd = Option.String("--cwd", {
|
|
123
|
+
description: "The project directory used to resolve the latest agent output (default: current working directory)",
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
async execute() {
|
|
127
|
+
const cwd = await realpath(this.cwd ?? process.cwd());
|
|
128
|
+
let latestState;
|
|
129
|
+
try {
|
|
130
|
+
latestState = await readLatestAgentState(cwd);
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
console.error(`Could not read the latest agent output for ${cwd}: ${error.message}`);
|
|
134
|
+
exit(1);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
if (!latestState) {
|
|
138
|
+
console.error(`No latest agent output found for ${cwd}`);
|
|
139
|
+
exit(1);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
console.log(latestState.outputDir);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
AgentLatestCommand.paths = [["agent", "latest"]];
|
|
146
|
+
AgentLatestCommand.usage = Command.Usage({
|
|
147
|
+
description: "Print the latest Allure agent output directory for the current project",
|
|
148
|
+
details: "This command prints the latest agent output directory recorded for the resolved project cwd.",
|
|
149
|
+
examples: [
|
|
150
|
+
["agent latest", "Print the latest agent output directory for the current project"],
|
|
151
|
+
["agent latest --cwd ./packages/cli", "Print the latest agent output directory for a specific project cwd"],
|
|
152
|
+
],
|
|
153
|
+
});
|
|
154
|
+
export class AgentStateDirCommand extends Command {
|
|
155
|
+
constructor() {
|
|
156
|
+
super(...arguments);
|
|
157
|
+
this.cwd = Option.String("--cwd", {
|
|
158
|
+
description: "The project directory used to resolve the agent state directory (default: current working directory)",
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
async execute() {
|
|
162
|
+
const cwd = await realpath(readOptionalString(this.cwd) ?? process.cwd());
|
|
163
|
+
console.log(resolveAgentStateDir(cwd));
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
AgentStateDirCommand.paths = [["agent", "state-dir"]];
|
|
167
|
+
AgentStateDirCommand.usage = Command.Usage({
|
|
168
|
+
description: "Print the Allure agent state directory for the current project",
|
|
169
|
+
details: "This command prints the resolved state directory used to persist latest-agent pointers for the current project cwd.",
|
|
170
|
+
examples: [
|
|
171
|
+
["agent state-dir", "Print the resolved state directory for the current project"],
|
|
172
|
+
["agent state-dir --cwd ./packages/cli", "Print the resolved state directory for a specific project cwd"],
|
|
173
|
+
],
|
|
174
|
+
});
|
|
175
|
+
export class AgentSelectCommand extends Command {
|
|
176
|
+
constructor() {
|
|
177
|
+
super(...arguments);
|
|
178
|
+
this.cwd = Option.String("--cwd", {
|
|
179
|
+
description: "The project directory used to resolve --latest and relative paths (default: current working directory)",
|
|
180
|
+
});
|
|
181
|
+
this.from = Option.String("--from", {
|
|
182
|
+
description: "The prior agent output directory to select tests from",
|
|
183
|
+
});
|
|
184
|
+
this.latest = Option.Boolean("--latest", {
|
|
185
|
+
description: "Use the latest recorded agent output for the current project cwd",
|
|
186
|
+
});
|
|
187
|
+
this.preset = Option.String("--preset", {
|
|
188
|
+
description: "The selection preset: review, failed, unsuccessful, or all (default: review)",
|
|
189
|
+
});
|
|
190
|
+
this.environments = Option.Array("--environment", {
|
|
191
|
+
description: "Filter selected tests by environment id. Repeat the option for multiple environments",
|
|
192
|
+
});
|
|
193
|
+
this.labels = Option.Array("--label", {
|
|
194
|
+
description: "Filter selected tests by exact label name=value. Repeat the option for multiple filters",
|
|
195
|
+
});
|
|
196
|
+
this.output = Option.String("--output,-o", {
|
|
197
|
+
description: "Write the resulting test plan to this file instead of printing it to stdout",
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
async execute() {
|
|
201
|
+
const cwd = await realpath(readOptionalString(this.cwd) ?? process.cwd());
|
|
202
|
+
const environments = readOptionalStringArray(this.environments);
|
|
203
|
+
const labels = readOptionalStringArray(this.labels);
|
|
204
|
+
const outputDir = await resolveAgentSelectionOutputDir({
|
|
205
|
+
cwd,
|
|
206
|
+
from: readOptionalString(this.from),
|
|
207
|
+
latest: readOptionalBoolean(this.latest),
|
|
208
|
+
});
|
|
209
|
+
const selection = await selectAgentTestPlan({
|
|
210
|
+
outputDir,
|
|
211
|
+
preset: normalizeAgentRerunPreset(readOptionalString(this.preset)),
|
|
212
|
+
environments: environments?.length ? environments : undefined,
|
|
213
|
+
labelFilters: parseAgentLabelFilters(labels),
|
|
214
|
+
});
|
|
215
|
+
if (!selection.testPlan.tests.length) {
|
|
216
|
+
console.error(`No tests matched selection in ${selection.outputDir}`);
|
|
217
|
+
exit(1);
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
const serialized = `${JSON.stringify(selection.testPlan, null, 2)}\n`;
|
|
221
|
+
const output = readOptionalString(this.output);
|
|
222
|
+
if (!output) {
|
|
223
|
+
console.log(serialized.trimEnd());
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
const outputPath = resolve(cwd, output);
|
|
227
|
+
await mkdir(dirname(outputPath), { recursive: true });
|
|
228
|
+
await writeFile(outputPath, serialized, "utf-8");
|
|
229
|
+
console.log(outputPath);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
AgentSelectCommand.paths = [["agent", "select"]];
|
|
233
|
+
AgentSelectCommand.usage = Command.Usage({
|
|
234
|
+
description: "Select tests from an existing agent output and emit a test plan",
|
|
235
|
+
details: "This command resolves a set of tests from a prior agent run and prints or writes a testplan.json payload.",
|
|
236
|
+
examples: [
|
|
237
|
+
["agent select --from ./out/agent-output", "Print a test plan for the default review-targeted tests"],
|
|
238
|
+
["agent select --latest --preset failed", "Print a test plan for failed tests from the latest project run"],
|
|
239
|
+
["agent select --from ./out/agent-output --output ./testplan.json", "Write the selected test plan to a file"],
|
|
240
|
+
],
|
|
241
|
+
});
|
|
242
|
+
export const executeAgentMode = async (params) => {
|
|
243
|
+
const { configPath, cwd: configuredCwd, output, expectations, environment, environmentName, silent, rerunFrom, rerunLatest, rerunPreset, rerunEnvironments, rerunLabels, args, } = params;
|
|
244
|
+
if (!args || !args.length) {
|
|
245
|
+
throw new UsageError("expecting command to be specified after --, e.g. allure agent -- npm run test");
|
|
246
|
+
}
|
|
247
|
+
const command = args[0];
|
|
248
|
+
const commandArgs = args.slice(1);
|
|
249
|
+
const cwd = await realpath(configuredCwd ?? process.cwd());
|
|
250
|
+
const commandString = `${command} ${commandArgs.join(" ")}`;
|
|
251
|
+
const hasRerunSource = !!rerunFrom || !!rerunLatest;
|
|
252
|
+
const hasRerunFilters = !!rerunPreset || !!rerunEnvironments?.length || !!rerunLabels?.length;
|
|
253
|
+
if (!hasRerunSource && hasRerunFilters) {
|
|
254
|
+
throw new UsageError("Use rerun filters only together with --rerun-from <path> or --rerun-latest");
|
|
255
|
+
}
|
|
256
|
+
const rerunContext = await createAgentTestPlanContext({
|
|
257
|
+
cwd,
|
|
258
|
+
from: rerunFrom,
|
|
259
|
+
latest: rerunLatest,
|
|
260
|
+
preset: normalizeAgentRerunPreset(rerunPreset),
|
|
261
|
+
environments: rerunEnvironments?.length ? rerunEnvironments : undefined,
|
|
262
|
+
labelFilters: parseAgentLabelFilters(rerunLabels),
|
|
263
|
+
});
|
|
264
|
+
const childEnvironmentVariables = {
|
|
265
|
+
...createChildAllureCliEnvironment("agent"),
|
|
266
|
+
...(rerunContext ? { ALLURE_TESTPLAN_PATH: rerunContext.testPlanPath } : {}),
|
|
267
|
+
};
|
|
268
|
+
try {
|
|
269
|
+
if (getActiveAllureCliCommand()) {
|
|
270
|
+
console.log(commandString);
|
|
271
|
+
const exitCode = await executeNestedAllureCommand({
|
|
272
|
+
command,
|
|
273
|
+
commandArgs,
|
|
274
|
+
cwd,
|
|
275
|
+
...(rerunContext ? { environmentVariables: { ALLURE_TESTPLAN_PATH: rerunContext.testPlanPath } } : {}),
|
|
276
|
+
silent,
|
|
277
|
+
});
|
|
278
|
+
exit(exitCode ?? -1);
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
const outputDir = output ? resolve(cwd, output) : await mkdtemp(join(tmpdir(), "allure-agent-"));
|
|
282
|
+
const expectationsPath = expectations ? resolve(cwd, expectations) : undefined;
|
|
283
|
+
const environmentOptions = {
|
|
284
|
+
environment,
|
|
285
|
+
environmentName,
|
|
286
|
+
};
|
|
287
|
+
normalizeCommandEnvironmentOptions(environmentOptions);
|
|
288
|
+
if (expectationsPath && isPathInside(outputDir, expectationsPath)) {
|
|
289
|
+
throw new UsageError(`--expectations path ${JSON.stringify(expectationsPath)} must not be inside the agent output directory ${JSON.stringify(outputDir)}`);
|
|
290
|
+
}
|
|
291
|
+
const config = await readConfig(cwd, configPath, {
|
|
292
|
+
output: outputDir,
|
|
293
|
+
plugins: {
|
|
294
|
+
agent: {
|
|
295
|
+
options: {
|
|
296
|
+
outputDir,
|
|
297
|
+
},
|
|
298
|
+
},
|
|
299
|
+
},
|
|
300
|
+
});
|
|
301
|
+
const resolvedEnvironment = resolveCommandEnvironment(config, environmentOptions);
|
|
302
|
+
try {
|
|
303
|
+
await rm(outputDir, { recursive: true });
|
|
304
|
+
}
|
|
305
|
+
catch (error) {
|
|
306
|
+
if (!isFileNotFoundError(error)) {
|
|
307
|
+
console.error("could not clean output directory", error);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
const startedAt = new Date().toISOString();
|
|
311
|
+
await persistLatestAgentState({
|
|
312
|
+
cwd,
|
|
313
|
+
outputDir,
|
|
314
|
+
expectationsPath,
|
|
315
|
+
command: commandString,
|
|
316
|
+
startedAt,
|
|
317
|
+
status: "running",
|
|
318
|
+
});
|
|
319
|
+
console.log(`agent output: ${outputDir}`);
|
|
320
|
+
if (expectationsPath) {
|
|
321
|
+
console.log(`agent expectations: ${expectationsPath}`);
|
|
322
|
+
}
|
|
323
|
+
console.log(commandString);
|
|
324
|
+
const allureReport = new AllureReport({
|
|
325
|
+
...config,
|
|
326
|
+
output: outputDir,
|
|
327
|
+
environment: resolvedEnvironment?.id,
|
|
328
|
+
open: false,
|
|
329
|
+
port: undefined,
|
|
330
|
+
qualityGate: undefined,
|
|
331
|
+
allureService: undefined,
|
|
332
|
+
realTime: false,
|
|
333
|
+
plugins: config.plugins,
|
|
334
|
+
});
|
|
335
|
+
const knownIssues = await allureReport.store.allKnownIssues();
|
|
336
|
+
const { globalExitCode } = await withProcessEnv({
|
|
337
|
+
ALLURE_AGENT_OUTPUT: outputDir,
|
|
338
|
+
ALLURE_AGENT_EXPECTATIONS: expectationsPath,
|
|
339
|
+
ALLURE_AGENT_COMMAND: commandString,
|
|
340
|
+
ALLURE_AGENT_PROJECT_ROOT: cwd,
|
|
341
|
+
ALLURE_AGENT_NAME: undefined,
|
|
342
|
+
ALLURE_AGENT_LOOP_ID: undefined,
|
|
343
|
+
ALLURE_AGENT_TASK_ID: undefined,
|
|
344
|
+
ALLURE_AGENT_CONVERSATION_ID: undefined,
|
|
345
|
+
}, async () => await executeAllureRun({
|
|
346
|
+
allureReport,
|
|
347
|
+
knownIssues,
|
|
348
|
+
cwd,
|
|
349
|
+
command,
|
|
350
|
+
commandArgs,
|
|
351
|
+
environmentVariables: childEnvironmentVariables,
|
|
352
|
+
environment: resolvedEnvironment?.id,
|
|
353
|
+
withQualityGate: false,
|
|
354
|
+
logs: "pipe",
|
|
355
|
+
silent,
|
|
356
|
+
ignoreLogs: false,
|
|
357
|
+
logProcessExit: false,
|
|
358
|
+
}));
|
|
359
|
+
await persistLatestAgentState({
|
|
360
|
+
cwd,
|
|
361
|
+
outputDir,
|
|
362
|
+
expectationsPath,
|
|
363
|
+
command: commandString,
|
|
364
|
+
startedAt,
|
|
365
|
+
finishedAt: new Date().toISOString(),
|
|
366
|
+
status: "finished",
|
|
367
|
+
exitCode: globalExitCode.actual ?? globalExitCode.original,
|
|
368
|
+
});
|
|
369
|
+
exit(globalExitCode.actual ?? globalExitCode.original);
|
|
370
|
+
}
|
|
371
|
+
finally {
|
|
372
|
+
await rerunContext?.cleanup();
|
|
373
|
+
}
|
|
374
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { AllureReport } from "@allurereport/core";
|
|
2
|
+
import { type KnownTestFailure } from "@allurereport/core-api";
|
|
3
|
+
import type { ExitCode, QualityGateValidationResult } from "@allurereport/plugin-api";
|
|
4
|
+
export type TestProcessResult = {
|
|
5
|
+
code: number | null;
|
|
6
|
+
stdout: string;
|
|
7
|
+
stderr: string;
|
|
8
|
+
qualityGateResults: QualityGateValidationResult[];
|
|
9
|
+
};
|
|
10
|
+
export type RunLogsMode = "pipe" | "inherit" | "ignore";
|
|
11
|
+
export declare const executeNestedAllureCommand: (params: {
|
|
12
|
+
command: string;
|
|
13
|
+
commandArgs: string[];
|
|
14
|
+
cwd: string;
|
|
15
|
+
environmentVariables?: Record<string, string>;
|
|
16
|
+
silent?: boolean;
|
|
17
|
+
}) => Promise<number | null>;
|
|
18
|
+
export declare const runTests: (params: {
|
|
19
|
+
allureReport: AllureReport;
|
|
20
|
+
knownIssues: KnownTestFailure[];
|
|
21
|
+
cwd: string;
|
|
22
|
+
command: string;
|
|
23
|
+
commandArgs: string[];
|
|
24
|
+
environmentVariables: Record<string, string>;
|
|
25
|
+
environment?: string;
|
|
26
|
+
withQualityGate: boolean;
|
|
27
|
+
silent?: boolean;
|
|
28
|
+
logs?: RunLogsMode;
|
|
29
|
+
logProcessExit?: boolean;
|
|
30
|
+
}) => Promise<TestProcessResult | null>;
|
|
31
|
+
export declare const executeAllureRun: (params: {
|
|
32
|
+
allureReport: AllureReport;
|
|
33
|
+
knownIssues: KnownTestFailure[];
|
|
34
|
+
cwd: string;
|
|
35
|
+
command: string;
|
|
36
|
+
commandArgs: string[];
|
|
37
|
+
environmentVariables?: Record<string, string>;
|
|
38
|
+
environment?: string;
|
|
39
|
+
withQualityGate: boolean;
|
|
40
|
+
silent?: boolean;
|
|
41
|
+
logs?: RunLogsMode;
|
|
42
|
+
ignoreLogs?: boolean;
|
|
43
|
+
maxRerun?: number;
|
|
44
|
+
logProcessExit?: boolean;
|
|
45
|
+
}) => Promise<{
|
|
46
|
+
globalExitCode: ExitCode;
|
|
47
|
+
testProcessResult: TestProcessResult | null;
|
|
48
|
+
}>;
|