@allurereport/core 3.18.0 → 3.19.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.
@@ -48,7 +48,7 @@ export declare class RealtimeEventsDispatcher implements RealtimeEventsDispatche
48
48
  }
49
49
  export declare class RealtimeSubscriber implements RealtimeSubscriberType {
50
50
  #private;
51
- constructor(emitter: EventEmitter<AllureStoreEvents>);
51
+ constructor(emitter: EventEmitter<AllureStoreEvents>, beforeTestResults?: () => void);
52
52
  onGlobalAttachment(listener: (payload: {
53
53
  attachment: ResultFile;
54
54
  fileName?: string;
@@ -9,7 +9,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
9
9
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
10
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
11
  };
12
- var _RealtimeEventsDispatcher_emitter, _RealtimeSubscriber_instances, _RealtimeSubscriber_emitter, _RealtimeSubscriber_handlers, _RealtimeSubscriber_onEvent, _RealtimeSubscriber_onBatchedEvent, _RealtimeSubscriber_createBatchHandler, _RealtimeSubscriber_runBatchHandler, _RealtimeSubscriber_disposeBatchHandler;
12
+ var _RealtimeEventsDispatcher_emitter, _RealtimeSubscriber_instances, _RealtimeSubscriber_emitter, _RealtimeSubscriber_beforeTestResults, _RealtimeSubscriber_handlers, _RealtimeSubscriber_onEvent, _RealtimeSubscriber_onBatchedEvent, _RealtimeSubscriber_createBatchHandler, _RealtimeSubscriber_runBatchHandler, _RealtimeSubscriber_disposeBatchHandler;
13
13
  import console from "node:console";
14
14
  import { setTimeout } from "node:timers/promises";
15
15
  export var RealtimeEvents;
@@ -77,11 +77,13 @@ export class RealtimeEventsDispatcher {
77
77
  }
78
78
  _RealtimeEventsDispatcher_emitter = new WeakMap();
79
79
  export class RealtimeSubscriber {
80
- constructor(emitter) {
80
+ constructor(emitter, beforeTestResults) {
81
81
  _RealtimeSubscriber_instances.add(this);
82
82
  _RealtimeSubscriber_emitter.set(this, void 0);
83
+ _RealtimeSubscriber_beforeTestResults.set(this, void 0);
83
84
  _RealtimeSubscriber_handlers.set(this, []);
84
85
  __classPrivateFieldSet(this, _RealtimeSubscriber_emitter, emitter, "f");
86
+ __classPrivateFieldSet(this, _RealtimeSubscriber_beforeTestResults, beforeTestResults, "f");
85
87
  }
86
88
  onGlobalAttachment(listener) {
87
89
  return __classPrivateFieldGet(this, _RealtimeSubscriber_instances, "m", _RealtimeSubscriber_onEvent).call(this, RealtimeEvents.GlobalAttachment, listener);
@@ -105,7 +107,10 @@ export class RealtimeSubscriber {
105
107
  return __classPrivateFieldGet(this, _RealtimeSubscriber_instances, "m", _RealtimeSubscriber_onEvent).call(this, RealtimeEvents.QualityGateResults, listener);
106
108
  }
107
109
  onTestResults(listener, options = {}) {
108
- return __classPrivateFieldGet(this, _RealtimeSubscriber_instances, "m", _RealtimeSubscriber_onBatchedEvent).call(this, RealtimeEvents.TestResult, listener, options);
110
+ return __classPrivateFieldGet(this, _RealtimeSubscriber_instances, "m", _RealtimeSubscriber_onBatchedEvent).call(this, RealtimeEvents.TestResult, (trIds) => {
111
+ __classPrivateFieldGet(this, _RealtimeSubscriber_beforeTestResults, "f")?.call(this);
112
+ return listener(trIds);
113
+ }, options);
109
114
  }
110
115
  onTestFixtureResults(listener, options = {}) {
111
116
  return __classPrivateFieldGet(this, _RealtimeSubscriber_instances, "m", _RealtimeSubscriber_onBatchedEvent).call(this, RealtimeEvents.TestFixtureResult, listener, options);
@@ -121,7 +126,7 @@ export class RealtimeSubscriber {
121
126
  __classPrivateFieldSet(this, _RealtimeSubscriber_handlers, [], "f");
122
127
  }
123
128
  }
124
- _RealtimeSubscriber_emitter = new WeakMap(), _RealtimeSubscriber_handlers = new WeakMap(), _RealtimeSubscriber_instances = new WeakSet(), _RealtimeSubscriber_onEvent = function _RealtimeSubscriber_onEvent(event, listener) {
129
+ _RealtimeSubscriber_emitter = new WeakMap(), _RealtimeSubscriber_beforeTestResults = new WeakMap(), _RealtimeSubscriber_handlers = new WeakMap(), _RealtimeSubscriber_instances = new WeakSet(), _RealtimeSubscriber_onEvent = function _RealtimeSubscriber_onEvent(event, listener) {
125
130
  const handler = createListenerHandler(listener);
126
131
  __classPrivateFieldGet(this, _RealtimeSubscriber_emitter, "f").on(event, handler);
127
132
  return () => {
@@ -1,2 +1,2 @@
1
- import type { HistoryTestResult, TestResult } from "@allurereport/core-api";
2
- export declare const isFlaky: (tr: TestResult, history: HistoryTestResult[]) => boolean;
1
+ import { type FlakyDetectionConfig, type HistoryTestResult, type TestResult } from "@allurereport/core-api";
2
+ export declare const createFlakyDetector: ({ historyDepth, includePassedTests, }?: FlakyDetectionConfig) => ((tr: TestResult, history: HistoryTestResult[]) => boolean);
@@ -1,12 +1,40 @@
1
- const MAX_LAST_HISTORY_SIZE = 5;
1
+ import { DEFAULT_ENVIRONMENT, } from "@allurereport/core-api";
2
+ const DEFAULT_HISTORY_DEPTH = 5;
3
+ const TRANSITION_HALF_LIFE = 2;
4
+ const STABILITY_PRIOR_WEIGHT = 3;
5
+ const FLAKY_SCORE_THRESHOLD = 30;
2
6
  const badStatuses = ["failed", "broken"];
3
- const isAllureClassicFlaky = (tr, history) => {
4
- if (history.length === 0 || !badStatuses.includes(tr.status)) {
7
+ const isFlakyByWeightedTransitions = (tr, history, historyDepth, includePassedTests) => {
8
+ const currentPassed = tr.status === "passed";
9
+ const isEligibleStatus = badStatuses.includes(tr.status) || (includePassedTests && currentPassed);
10
+ if (historyDepth === -1 || !isEligibleStatus) {
5
11
  return false;
6
12
  }
7
- const limitedLastHistory = history.slice(0, MAX_LAST_HISTORY_SIZE);
8
- const limitedLastHistoryStatuses = limitedLastHistory.map((h) => h.status);
9
- return (limitedLastHistoryStatuses.includes("passed") &&
10
- limitedLastHistoryStatuses.indexOf("passed") < limitedLastHistoryStatuses.lastIndexOf("failed"));
13
+ let previousPassed = currentPassed;
14
+ let comparisons = 0;
15
+ let weightedTransitions = 0;
16
+ let totalWeight = 0;
17
+ for (const result of history) {
18
+ if (historyDepth !== 0 && comparisons >= historyDepth) {
19
+ break;
20
+ }
21
+ if (result.id === tr.id ||
22
+ (result.environment ?? DEFAULT_ENVIRONMENT) !== (tr.environment ?? DEFAULT_ENVIRONMENT) ||
23
+ (result.status !== "passed" && !badStatuses.includes(result.status))) {
24
+ continue;
25
+ }
26
+ const passed = result.status === "passed";
27
+ const weight = 2 ** (-comparisons / TRANSITION_HALF_LIFE);
28
+ if (passed !== previousPassed) {
29
+ weightedTransitions += weight;
30
+ }
31
+ totalWeight += weight;
32
+ previousPassed = passed;
33
+ comparisons++;
34
+ }
35
+ const score = (100 * weightedTransitions) / (STABILITY_PRIOR_WEIGHT + totalWeight);
36
+ return score >= FLAKY_SCORE_THRESHOLD;
37
+ };
38
+ export const createFlakyDetector = ({ historyDepth = DEFAULT_HISTORY_DEPTH, includePassedTests = false, } = {}) => {
39
+ return (tr, history) => isFlakyByWeightedTransitions(tr, history, historyDepth, includePassedTests);
11
40
  };
12
- export const isFlaky = (tr, history) => tr.flaky || isAllureClassicFlaky(tr, history);
@@ -1,18 +1,12 @@
1
1
  import type { AllurePerformanceResult } from "@allurereport/core-api";
2
2
  export declare const PERF_METRICS_FILE = "performance.json";
3
3
  export declare const perfMetricsFileName: (reportUuid: string) => string;
4
- export type PerfMetricSpan = {
5
- name: string;
6
- startTimeMs: number;
7
- durationMs: number;
8
- };
9
- export type PerfMetricSummary = {
10
- name: string;
11
- count: number;
12
- totalMs: number;
13
- minMs: number;
14
- maxMs: number;
15
- avgMs: number;
4
+ type PerfMetricMetadata = {
5
+ title?: string;
6
+ unit?: string;
7
+ group?: string;
8
+ groupTitle?: string;
9
+ better?: "neutral";
16
10
  };
17
11
  export declare const PERF_METRIC_NAMES: {
18
12
  readonly allureTotal: "allure.total";
@@ -22,17 +16,35 @@ export declare const PERF_METRIC_NAMES: {
22
16
  readonly restoreStateStoreRestore: "restoreState.storeRestore";
23
17
  readonly generateTotal: "generate.total";
24
18
  readonly generateReadResults: "generate.readResults";
19
+ readonly generateReadResultsXcresultCheck: "generate.readResults.xcresultCheck";
20
+ readonly generateReadResultsReaddir: "generate.readResults.readdir";
21
+ readonly generateReadResultsFiles: "generate.readResults.files";
22
+ readonly generateReadResultsRealpath: "generate.readResults.realpath";
23
+ readonly generateReadResultsReaderRead: "generate.readResults.reader.read";
25
24
  readonly generatePluginsDone: "generate.plugins.done";
25
+ readonly storeVisitTestResultConvert: "store.visitTestResult.convert";
26
+ readonly storeVisitTestResultDefaultLabels: "store.visitTestResult.defaultLabels";
27
+ readonly storeVisitTestResultEnvironment: "store.visitTestResult.environment";
28
+ readonly storeVisitTestResultRetry: "store.visitTestResult.retry";
29
+ readonly storeVisitTestResultHistory: "store.visitTestResult.history";
30
+ readonly storeVisitTestResultResolution: "store.visitTestResult.resolution";
31
+ readonly storeVisitTestResultIndexes: "store.visitTestResult.indexes";
32
+ readonly storeVisitAttachmentFileMetadata: "store.visitAttachmentFile.metadata";
26
33
  readonly publishUploadTotal: "publish.upload.total";
27
34
  readonly summaryGenerate: "summary.generate";
28
35
  };
29
36
  export declare const PERF_METRIC_PREFIXES: {
37
+ readonly generatePlugin: "generate.plugin.";
30
38
  readonly generatePluginDone: "generate.plugin.done.";
31
39
  readonly publishUploadPlugin: "publish.upload.plugin.";
32
40
  };
33
41
  export declare const isPerfMetricsEnabled: () => boolean;
34
42
  export declare const startPerfSpan: (name: string) => (() => void);
35
43
  export declare const measurePerf: <T>(name: string, fn: () => Promise<T>) => Promise<T>;
44
+ export declare const measurePerfAggregate: <T>(name: string, fn: () => Promise<T>) => Promise<T>;
45
+ export declare const measurePerfAggregateSync: <T>(name: string, fn: () => T) => T;
46
+ export declare const incrementPerfCounter: (name: string, value?: number, metadata?: PerfMetricMetadata) => void;
36
47
  export declare const getPerfMetricsResults: () => AllurePerformanceResult[];
37
48
  export declare const writePerfMetrics: (output: string, fileName?: string) => Promise<boolean>;
38
49
  export declare const resetPerfMetrics: () => void;
50
+ export {};
@@ -7,6 +7,8 @@ export const perfMetricsFileName = (reportUuid) => `${reportUuid}-perf.json`;
7
7
  const MARK_PREFIX = "allure:perf:";
8
8
  const ENABLED_VALUES = new Set(["1", "true", "yes", "on"]);
9
9
  const SPANS = [];
10
+ const AGGREGATES = new Map();
11
+ const COUNTERS = new Map();
10
12
  const MARKS = new Set();
11
13
  const MEASURES = new Set();
12
14
  let sequence = 0;
@@ -19,28 +21,46 @@ export const PERF_METRIC_NAMES = {
19
21
  restoreStateStoreRestore: "restoreState.storeRestore",
20
22
  generateTotal: "generate.total",
21
23
  generateReadResults: "generate.readResults",
24
+ generateReadResultsXcresultCheck: "generate.readResults.xcresultCheck",
25
+ generateReadResultsReaddir: "generate.readResults.readdir",
26
+ generateReadResultsFiles: "generate.readResults.files",
27
+ generateReadResultsRealpath: "generate.readResults.realpath",
28
+ generateReadResultsReaderRead: "generate.readResults.reader.read",
22
29
  generatePluginsDone: "generate.plugins.done",
30
+ storeVisitTestResultConvert: "store.visitTestResult.convert",
31
+ storeVisitTestResultDefaultLabels: "store.visitTestResult.defaultLabels",
32
+ storeVisitTestResultEnvironment: "store.visitTestResult.environment",
33
+ storeVisitTestResultRetry: "store.visitTestResult.retry",
34
+ storeVisitTestResultHistory: "store.visitTestResult.history",
35
+ storeVisitTestResultResolution: "store.visitTestResult.resolution",
36
+ storeVisitTestResultIndexes: "store.visitTestResult.indexes",
37
+ storeVisitAttachmentFileMetadata: "store.visitAttachmentFile.metadata",
23
38
  publishUploadTotal: "publish.upload.total",
24
39
  summaryGenerate: "summary.generate",
25
40
  };
26
41
  export const PERF_METRIC_PREFIXES = {
42
+ generatePlugin: "generate.plugin.",
27
43
  generatePluginDone: "generate.plugin.done.",
28
44
  publishUploadPlugin: "publish.upload.plugin.",
29
45
  };
30
- const getCoveredDurationSummary = () => {
31
- if (SPANS.length === 0) {
46
+ const getCoveredTiming = () => {
47
+ const timings = [
48
+ ...SPANS.map(({ startTimeMs, durationMs }) => ({
49
+ startTimeMs,
50
+ stopTimeMs: startTimeMs + durationMs,
51
+ })),
52
+ ...AGGREGATES.values(),
53
+ ...COUNTERS.values(),
54
+ ];
55
+ if (timings.length === 0) {
32
56
  return undefined;
33
57
  }
34
- const startTimeMs = Math.min(...SPANS.map(({ startTimeMs }) => startTimeMs));
35
- const endTimeMs = Math.max(...SPANS.map(({ startTimeMs, durationMs }) => startTimeMs + durationMs));
36
- const durationMs = round(endTimeMs - startTimeMs);
58
+ const startTimeMs = Math.min(...timings.map(({ startTimeMs }) => startTimeMs));
59
+ const stopTimeMs = Math.max(...timings.map(({ stopTimeMs }) => stopTimeMs));
37
60
  return {
38
- name: PERF_METRIC_NAMES.allureTotal,
39
- count: 1,
40
- totalMs: durationMs,
41
- minMs: durationMs,
42
- maxMs: durationMs,
43
- avgMs: durationMs,
61
+ startTimeMs,
62
+ stopTimeMs,
63
+ durationMs: round(stopTimeMs - startTimeMs),
44
64
  };
45
65
  };
46
66
  export const isPerfMetricsEnabled = () => ENABLED_VALUES.has((process.env.ALLURE_PERF_METRICS ?? "").toLowerCase());
@@ -91,8 +111,80 @@ export const measurePerf = async (name, fn) => {
91
111
  end();
92
112
  }
93
113
  };
114
+ const recordPerfTiming = (name, durationMs, startTimeMs) => {
115
+ if (!isPerfMetricsEnabled()) {
116
+ return;
117
+ }
118
+ const current = AGGREGATES.get(name);
119
+ if (!current) {
120
+ AGGREGATES.set(name, {
121
+ name,
122
+ count: 1,
123
+ totalMs: durationMs,
124
+ startTimeMs,
125
+ stopTimeMs: startTimeMs + durationMs,
126
+ });
127
+ return;
128
+ }
129
+ current.count += 1;
130
+ current.totalMs += durationMs;
131
+ current.startTimeMs = Math.min(current.startTimeMs, startTimeMs);
132
+ current.stopTimeMs = Math.max(current.stopTimeMs, startTimeMs + durationMs);
133
+ };
134
+ export const measurePerfAggregate = async (name, fn) => {
135
+ if (!isPerfMetricsEnabled()) {
136
+ return fn();
137
+ }
138
+ const startTimeMs = performance.now();
139
+ try {
140
+ return await fn();
141
+ }
142
+ finally {
143
+ recordPerfTiming(name, performance.now() - startTimeMs, startTimeMs);
144
+ }
145
+ };
146
+ export const measurePerfAggregateSync = (name, fn) => {
147
+ if (!isPerfMetricsEnabled()) {
148
+ return fn();
149
+ }
150
+ const startTimeMs = performance.now();
151
+ try {
152
+ return fn();
153
+ }
154
+ finally {
155
+ recordPerfTiming(name, performance.now() - startTimeMs, startTimeMs);
156
+ }
157
+ };
158
+ export const incrementPerfCounter = (name, value = 1, metadata) => {
159
+ if (!isPerfMetricsEnabled()) {
160
+ return;
161
+ }
162
+ const timeMs = performance.now();
163
+ const current = COUNTERS.get(name);
164
+ if (!current) {
165
+ COUNTERS.set(name, {
166
+ name,
167
+ value,
168
+ startTimeMs: timeMs,
169
+ stopTimeMs: timeMs,
170
+ ...(metadata ? { metadata } : {}),
171
+ });
172
+ return;
173
+ }
174
+ current.value += value;
175
+ current.stopTimeMs = timeMs;
176
+ current.metadata ?? (current.metadata = metadata);
177
+ };
178
+ const metricResult = (key, value, startTimeMs, stopTimeMs, metadata) => ({
179
+ id: randomUUID(),
180
+ key,
181
+ value: round(value),
182
+ start: round(performance.timeOrigin + startTimeMs),
183
+ stop: round(performance.timeOrigin + stopTimeMs),
184
+ ...metadata,
185
+ });
94
186
  export const getPerfMetricsResults = () => {
95
- const totalSummary = getCoveredDurationSummary();
187
+ const coveredTiming = getCoveredTiming();
96
188
  const results = SPANS.map((span) => ({
97
189
  id: randomUUID(),
98
190
  key: span.name,
@@ -100,15 +192,21 @@ export const getPerfMetricsResults = () => {
100
192
  start: round(performance.timeOrigin + span.startTimeMs),
101
193
  stop: round(performance.timeOrigin + span.startTimeMs + span.durationMs),
102
194
  }));
103
- if (totalSummary) {
195
+ if (coveredTiming) {
104
196
  results.unshift({
105
197
  id: randomUUID(),
106
198
  key: PERF_METRIC_NAMES.allureTotal,
107
- value: totalSummary.avgMs,
108
- start: round(performance.timeOrigin + Math.min(...SPANS.map(({ startTimeMs }) => startTimeMs))),
109
- stop: round(performance.timeOrigin + Math.max(...SPANS.map(({ startTimeMs, durationMs }) => startTimeMs + durationMs))),
199
+ value: coveredTiming.durationMs,
200
+ start: round(performance.timeOrigin + coveredTiming.startTimeMs),
201
+ stop: round(performance.timeOrigin + coveredTiming.stopTimeMs),
110
202
  });
111
203
  }
204
+ for (const aggregate of AGGREGATES.values()) {
205
+ results.push(metricResult(`${aggregate.name}.totalMs`, aggregate.totalMs, aggregate.startTimeMs, aggregate.stopTimeMs), metricResult(`${aggregate.name}.avgMs`, aggregate.totalMs / aggregate.count, aggregate.startTimeMs, aggregate.stopTimeMs));
206
+ }
207
+ for (const counter of COUNTERS.values()) {
208
+ results.push(metricResult(counter.name, counter.value, counter.startTimeMs, counter.stopTimeMs, counter.metadata));
209
+ }
112
210
  return results;
113
211
  };
114
212
  export const writePerfMetrics = async (output, fileName = PERF_METRICS_FILE) => {
@@ -123,6 +221,8 @@ export const writePerfMetrics = async (output, fileName = PERF_METRICS_FILE) =>
123
221
  };
124
222
  export const resetPerfMetrics = () => {
125
223
  SPANS.length = 0;
224
+ AGGREGATES.clear();
225
+ COUNTERS.clear();
126
226
  sequence = 0;
127
227
  for (const mark of MARKS) {
128
228
  performance.clearMarks(mark);
@@ -3,6 +3,7 @@ export declare class RealtimeChannel {
3
3
  #private;
4
4
  readonly dispatcher: RealtimeEventsDispatcher;
5
5
  readonly subscriber: RealtimeSubscriber;
6
+ constructor(beforeTestResults?: () => void);
6
7
  onResultLikeChanged(listener: () => void): () => void;
7
8
  close(): void;
8
9
  }
@@ -7,10 +7,10 @@ var _RealtimeChannel_emitter;
7
7
  import { EventEmitter } from "node:events";
8
8
  import { RealtimeEvents, RealtimeEventsDispatcher, RealtimeSubscriber } from "./event.js";
9
9
  export class RealtimeChannel {
10
- constructor() {
10
+ constructor(beforeTestResults) {
11
11
  _RealtimeChannel_emitter.set(this, new EventEmitter());
12
12
  this.dispatcher = new RealtimeEventsDispatcher(__classPrivateFieldGet(this, _RealtimeChannel_emitter, "f"));
13
- this.subscriber = new RealtimeSubscriber(__classPrivateFieldGet(this, _RealtimeChannel_emitter, "f"));
13
+ this.subscriber = new RealtimeSubscriber(__classPrivateFieldGet(this, _RealtimeChannel_emitter, "f"), beforeTestResults);
14
14
  }
15
15
  onResultLikeChanged(listener) {
16
16
  __classPrivateFieldGet(this, _RealtimeChannel_emitter, "f").on(RealtimeEvents.TestResult, listener);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@allurereport/core",
3
- "version": "3.18.0",
3
+ "version": "3.19.1",
4
4
  "description": "Collection of generic Allure utilities used across the entire project",
5
5
  "keywords": [
6
6
  "allure"
@@ -25,26 +25,26 @@
25
25
  "lint:fix": "oxlint --import-plugin --fix src test features stories"
26
26
  },
27
27
  "dependencies": {
28
- "@allurereport/ci": "3.18.0",
29
- "@allurereport/cli-commons": "3.18.0",
30
- "@allurereport/core-api": "3.18.0",
31
- "@allurereport/plugin-agent": "3.18.0",
32
- "@allurereport/plugin-allure2": "3.18.0",
33
- "@allurereport/plugin-api": "3.18.0",
34
- "@allurereport/plugin-awesome": "3.18.0",
35
- "@allurereport/plugin-classic": "3.18.0",
36
- "@allurereport/plugin-csv": "3.18.0",
37
- "@allurereport/plugin-dashboard": "3.18.0",
38
- "@allurereport/plugin-jira": "3.18.0",
39
- "@allurereport/plugin-log": "3.18.0",
40
- "@allurereport/plugin-progress": "3.18.0",
41
- "@allurereport/plugin-slack": "3.18.0",
42
- "@allurereport/plugin-testops": "3.18.0",
43
- "@allurereport/plugin-testplan": "3.18.0",
44
- "@allurereport/reader": "3.18.0",
45
- "@allurereport/reader-api": "3.18.0",
46
- "@allurereport/service": "3.18.0",
47
- "@allurereport/summary": "3.18.0",
28
+ "@allurereport/ci": "3.19.1",
29
+ "@allurereport/cli-commons": "3.19.1",
30
+ "@allurereport/core-api": "3.19.1",
31
+ "@allurereport/plugin-agent": "3.19.1",
32
+ "@allurereport/plugin-allure2": "3.19.1",
33
+ "@allurereport/plugin-api": "3.19.1",
34
+ "@allurereport/plugin-awesome": "3.19.1",
35
+ "@allurereport/plugin-classic": "3.19.1",
36
+ "@allurereport/plugin-csv": "3.19.1",
37
+ "@allurereport/plugin-dashboard": "3.19.1",
38
+ "@allurereport/plugin-jira": "3.19.1",
39
+ "@allurereport/plugin-log": "3.19.1",
40
+ "@allurereport/plugin-progress": "3.19.1",
41
+ "@allurereport/plugin-slack": "3.19.1",
42
+ "@allurereport/plugin-testops": "3.19.1",
43
+ "@allurereport/plugin-testplan": "3.19.1",
44
+ "@allurereport/reader": "3.19.1",
45
+ "@allurereport/reader-api": "3.19.1",
46
+ "@allurereport/service": "3.19.1",
47
+ "@allurereport/summary": "3.19.1",
48
48
  "glob": "^13.0.6",
49
49
  "handlebars": "^4.7.9",
50
50
  "jiti": "^2.5.1",
@@ -58,7 +58,7 @@
58
58
  "@types/node": "^20",
59
59
  "@types/zip-stream": "^7.0.0",
60
60
  "@vitest/runner": "^2",
61
- "@vitest/snapshot": "^2.1.9",
61
+ "@vitest/snapshot": "^5.0.1",
62
62
  "allure-js-commons": "^3",
63
63
  "allure-vitest": "^3",
64
64
  "rimraf": "^6",