@allurereport/plugin-api 3.0.0-beta.9 → 3.0.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/dist/config.d.ts CHANGED
@@ -1,13 +1,25 @@
1
+ import type { DefaultLabelsConfig, EnvironmentsConfig, ReportVariables } from "@allurereport/core-api";
1
2
  import type { PluginDescriptor } from "./plugin.js";
2
3
  import type { QualityGateConfig } from "./qualityGate.js";
3
- export type DefaultLabelsConfig = Record<string, string | string[]>;
4
4
  export interface Config {
5
5
  name?: string;
6
6
  output?: string;
7
+ open?: boolean;
8
+ port?: string;
7
9
  historyPath?: string;
8
10
  knownIssuesPath?: string;
9
- qualityGate?: QualityGateConfig;
10
- plugins?: Record<string, PluginDescriptor>;
11
11
  defaultLabels?: DefaultLabelsConfig;
12
+ stage?: string;
13
+ environment?: string;
14
+ environments?: EnvironmentsConfig;
15
+ variables?: ReportVariables;
16
+ plugins?: Record<string, PluginDescriptor>;
17
+ appendHistory?: boolean;
18
+ qualityGate?: QualityGateConfig;
19
+ allureService?: {
20
+ url?: string;
21
+ project?: string;
22
+ accessToken?: string;
23
+ };
12
24
  }
13
25
  export declare const defineConfig: (allureConfig: Config) => Config;
package/dist/index.d.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  export * from "./config.js";
2
2
  export type * from "./plugin.js";
3
3
  export type * from "./qualityGate.js";
4
- export type * from "./store.js";
4
+ export * from "./store.js";
5
5
  export type * from "./resultFile.js";
6
6
  export * from "./utils/misc.js";
7
7
  export * from "./utils/tree.js";
8
+ export * from "./utils/summary.js";
package/dist/index.js CHANGED
@@ -1,3 +1,5 @@
1
1
  export * from "./config.js";
2
+ export * from "./store.js";
2
3
  export * from "./utils/misc.js";
3
4
  export * from "./utils/tree.js";
5
+ export * from "./utils/summary.js";
package/dist/plugin.d.ts CHANGED
@@ -1,3 +1,6 @@
1
+ import type { AttachmentLink, CiDescriptor, Statistic, TestError, TestResult, TestStatus } from "@allurereport/core-api";
2
+ import type { QualityGateValidationResult } from "./qualityGate.js";
3
+ import type { ResultFile } from "./resultFile.js";
1
4
  import type { AllureStore } from "./store.js";
2
5
  export interface PluginDescriptor {
3
6
  import?: string;
@@ -5,30 +8,74 @@ export interface PluginDescriptor {
5
8
  options?: Record<string, any>;
6
9
  }
7
10
  export interface ReportFiles {
8
- addFile(path: string, data: Buffer): Promise<void>;
11
+ addFile(path: string, data: Buffer): Promise<string>;
9
12
  }
10
13
  export interface PluginState {
11
14
  set(key: string, value: any): Promise<void>;
12
- get(key: string): Promise<void>;
15
+ get<T>(key: string): Promise<T>;
13
16
  unset(key: string): Promise<void>;
14
17
  }
15
18
  export interface PluginContext {
19
+ id: string;
20
+ publish: boolean;
16
21
  state: PluginState;
17
22
  allureVersion: string;
18
23
  reportUuid: string;
19
24
  reportName: string;
20
25
  reportFiles: ReportFiles;
26
+ reportUrl?: string;
27
+ ci?: CiDescriptor;
28
+ }
29
+ export type SummaryTestResult = Pick<TestResult, "name" | "id" | "status" | "duration">;
30
+ export interface PluginSummary {
31
+ href?: string;
32
+ remoteHref?: string;
33
+ jobHref?: string;
34
+ pullRequestHref?: string;
35
+ name: string;
36
+ stats: Statistic;
37
+ status: TestStatus;
38
+ duration: number;
39
+ plugin?: string;
40
+ newTests?: SummaryTestResult[];
41
+ flakyTests?: SummaryTestResult[];
42
+ retryTests?: SummaryTestResult[];
43
+ createdAt?: number;
44
+ meta?: Record<string, any>;
45
+ }
46
+ export interface ExitCode {
47
+ actual?: number;
48
+ original: number;
49
+ }
50
+ export interface PluginGlobals {
51
+ exitCode?: ExitCode;
52
+ errors: TestError[];
53
+ attachments: AttachmentLink[];
21
54
  }
22
55
  export interface BatchOptions {
23
56
  maxTimeout?: number;
24
57
  }
25
- export interface Realtime {
26
- onTestResults(listener: (trIds: string[]) => Promise<void>, options?: BatchOptions): void;
27
- onTestFixtureResults(listener: (tfrIds: string[]) => Promise<void>, options?: BatchOptions): void;
28
- onAttachmentFiles(listener: (afIds: string[]) => Promise<void>, options?: BatchOptions): void;
58
+ export interface RealtimeSubscriber {
59
+ onGlobalAttachment(listener: (attachment: ResultFile) => Promise<void>): () => void;
60
+ onGlobalExitCode(listener: (payload: ExitCode) => Promise<void>): () => void;
61
+ onGlobalError(listener: (error: TestError) => Promise<void>): () => void;
62
+ onQualityGateResults(listener: (payload: QualityGateValidationResult[]) => Promise<void>): () => void;
63
+ onTestResults(listener: (trIds: string[]) => Promise<void>, options?: BatchOptions): () => void;
64
+ onTestFixtureResults(listener: (tfrIds: string[]) => Promise<void>, options?: BatchOptions): () => void;
65
+ onAttachmentFiles(listener: (afIds: string[]) => Promise<void>, options?: BatchOptions): () => void;
66
+ }
67
+ export interface RealtimeEventsDispatcher {
68
+ sendGlobalAttachment(attachment: ResultFile): void;
69
+ sendGlobalExitCode(payload: ExitCode): void;
70
+ sendGlobalError(error: TestError): void;
71
+ sendQualityGateResults(payload: QualityGateValidationResult[]): void;
72
+ sendTestResult(trId: string): void;
73
+ sendTestFixtureResult(tfrId: string): void;
74
+ sendAttachmentFile(afId: string): void;
29
75
  }
30
76
  export interface Plugin {
31
- start?(context: PluginContext, store: AllureStore, realtime: Realtime): Promise<void>;
77
+ start?(context: PluginContext, store: AllureStore, realtime: RealtimeSubscriber): Promise<void>;
32
78
  update?(context: PluginContext, store: AllureStore): Promise<void>;
33
79
  done?(context: PluginContext, store: AllureStore): Promise<void>;
80
+ info?(context: PluginContext, store: AllureStore): Promise<PluginSummary>;
34
81
  }
@@ -1,44 +1,38 @@
1
- import type { AllureStore } from "./store.js";
2
- export type QualityGateRules = Record<string, any>;
3
- export type QualityGateRulesBaseMeta<T> = {
4
- type: T;
5
- };
6
- export type QualityGateLabelsRulesMeta = QualityGateRulesBaseMeta<"label"> & {
7
- name: string;
8
- value: string;
9
- };
10
- export type QualityGateParametersRulesMeta = QualityGateRulesBaseMeta<"parameter"> & {
11
- name: string;
12
- value: string;
13
- };
14
- export type QualityGateLabelsEnforceConfig = {
15
- type: "label";
16
- name: string;
17
- value: string;
18
- rules: QualityGateRules;
19
- };
20
- export type QualityGateParametersEnforceConfig = {
21
- type: "parameter";
22
- name: string;
23
- value: string;
24
- rules: QualityGateRules;
25
- };
26
- export type QualityGateRulesMeta = Omit<QualityGateLabelsRulesMeta, "rules"> | Omit<QualityGateParametersRulesMeta, "rules">;
27
- export type QualityGateEnforceConfig = QualityGateLabelsEnforceConfig | QualityGateParametersEnforceConfig;
1
+ import type { KnownTestFailure, TestResult } from "@allurereport/core-api";
28
2
  export type QualityGateValidationResult = {
29
3
  success: boolean;
4
+ expected: any;
5
+ actual: any;
30
6
  rule: string;
31
- meta?: QualityGateRulesMeta;
32
- expected?: number;
33
- actual?: number;
34
- message?: string;
7
+ message: string;
35
8
  };
36
- export interface QualityGateValidator {
37
- validate(store: AllureStore): Promise<QualityGateValidationResult>;
9
+ export type QualityGateRules = Record<string, any> & {
10
+ id?: string;
11
+ fastFail?: boolean;
12
+ filter?: (tr: TestResult) => boolean;
13
+ };
14
+ export type QualityGateRuleResult = {
15
+ success: boolean;
16
+ actual: any;
17
+ };
18
+ export interface QualityGateRuleState<T> {
19
+ getResult(): T | undefined;
20
+ setResult(value: T): void;
38
21
  }
39
- export type QualityGateValidatorConstructor = new (limit: number, meta?: QualityGateRulesMeta) => QualityGateValidator;
22
+ export type QualityGateRule<T = any, K = T> = {
23
+ rule: string;
24
+ message: (payload: {
25
+ expected: T;
26
+ actual: T;
27
+ }) => string;
28
+ validate: (payload: {
29
+ expected: T;
30
+ trs: TestResult[];
31
+ knownIssues: KnownTestFailure[];
32
+ state: QualityGateRuleState<K>;
33
+ }) => Promise<QualityGateRuleResult>;
34
+ };
40
35
  export type QualityGateConfig = {
41
- rules?: QualityGateRules;
42
- enforce?: QualityGateEnforceConfig[];
43
- validators?: Record<string, QualityGateValidatorConstructor>;
36
+ rules?: QualityGateRules[];
37
+ use?: QualityGateRule[];
44
38
  };
package/dist/store.d.ts CHANGED
@@ -1,15 +1,24 @@
1
- import type { AttachmentLink, HistoryDataPoint, HistoryTestResult, KnownTestFailure, Statistic, TestCase, TestFixtureResult, TestResult } from "@allurereport/core-api";
1
+ import type { AttachmentLink, HistoryDataPoint, HistoryTestResult, KnownTestFailure, ReportVariables, Statistic, TestCase, TestEnvGroup, TestError, TestFixtureResult, TestResult } from "@allurereport/core-api";
2
+ import type { ExitCode } from "./plugin.js";
3
+ import type { QualityGateValidationResult } from "./qualityGate.js";
2
4
  import type { ResultFile } from "./resultFile.js";
5
+ export type TestResultFilter = (testResult: TestResult) => boolean;
3
6
  export interface AllureStore {
4
7
  allTestCases: () => Promise<TestCase[]>;
5
8
  allTestResults: (options?: {
6
- includeHidden: boolean;
9
+ includeHidden?: boolean;
7
10
  }) => Promise<TestResult[]>;
8
11
  allAttachments: () => Promise<AttachmentLink[]>;
9
12
  allMetadata: () => Promise<Record<string, any>>;
10
13
  allFixtures: () => Promise<TestFixtureResult[]>;
11
14
  allHistoryDataPoints: () => Promise<HistoryDataPoint[]>;
15
+ allHistoryDataPointsByEnvironment: (environment: string) => Promise<HistoryDataPoint[]>;
12
16
  allKnownIssues: () => Promise<KnownTestFailure[]>;
17
+ allNewTestResults: () => Promise<TestResult[]>;
18
+ qualityGateResults: () => Promise<QualityGateValidationResult[]>;
19
+ globalExitCode: () => Promise<ExitCode | undefined>;
20
+ allGlobalErrors: () => Promise<TestError[]>;
21
+ allGlobalAttachments: () => Promise<AttachmentLink[]>;
13
22
  testCaseById: (tcId: string) => Promise<TestCase | undefined>;
14
23
  testResultById: (trId: string) => Promise<TestResult | undefined>;
15
24
  attachmentById: (attachmentId: string) => Promise<AttachmentLink | undefined>;
@@ -17,8 +26,9 @@ export interface AllureStore {
17
26
  metadataByKey: <T>(key: string) => Promise<T | undefined>;
18
27
  testResultsByTcId: (tcId: string) => Promise<TestResult[]>;
19
28
  attachmentsByTrId: (trId: string) => Promise<AttachmentLink[]>;
29
+ retriesByTr: (tr: TestResult) => Promise<TestResult[]>;
20
30
  retriesByTrId: (trId: string) => Promise<TestResult[]>;
21
- historyByTrId: (trId: string) => Promise<HistoryTestResult[]>;
31
+ historyByTrId: (trId: string) => Promise<HistoryTestResult[] | undefined>;
22
32
  fixturesByTrId: (trId: string) => Promise<TestFixtureResult[]>;
23
33
  failedTestResults: () => Promise<TestResult[]>;
24
34
  unknownFailedTestResults: () => Promise<TestResult[]>;
@@ -27,4 +37,45 @@ export interface AllureStore {
27
37
  [x: string]: TestResult[];
28
38
  }>;
29
39
  testsStatistic: (filter?: (testResult: TestResult) => boolean) => Promise<Statistic>;
40
+ allEnvironments: () => Promise<string[]>;
41
+ testResultsByEnvironment: (env: string) => Promise<TestResult[]>;
42
+ allTestEnvGroups: () => Promise<TestEnvGroup[]>;
43
+ allVariables: () => Promise<Record<string, any>>;
44
+ envVariables: (env: string) => Promise<Record<string, any>>;
45
+ }
46
+ export interface AllureStoreDump {
47
+ testResults: Record<string, TestResult>;
48
+ attachments: Record<string, AttachmentLink>;
49
+ globalAttachments: AttachmentLink[];
50
+ globalErrors: TestError[];
51
+ testCases: Record<string, TestCase>;
52
+ fixtures: Record<string, TestFixtureResult>;
53
+ environments: string[];
54
+ reportVariables: ReportVariables;
55
+ qualityGateResultsByRules: Record<string, QualityGateValidationResult>;
56
+ indexAttachmentByTestResult: Record<string, string[]>;
57
+ indexTestResultByHistoryId: Record<string, string[]>;
58
+ indexTestResultByTestCase: Record<string, string[]>;
59
+ indexLatestEnvTestResultByHistoryId: Record<string, string>;
60
+ indexAttachmentByFixture: Record<string, string[]>;
61
+ indexFixturesByTestResult: Record<string, string[]>;
62
+ indexKnownByHistoryId: Record<string, KnownTestFailure[]>;
63
+ }
64
+ export declare enum AllureStoreDumpFiles {
65
+ TestResults = "test-results.json",
66
+ TestCases = "test-cases.json",
67
+ Fixtures = "fixtures.json",
68
+ GlobalErrors = "global-errors.json",
69
+ GlobalAttachments = "global-attachments.json",
70
+ Attachments = "attachments.json",
71
+ Environments = "environments.json",
72
+ ReportVariables = "report-variables.json",
73
+ IndexAttachmentsByTestResults = "index-attachments-by-test-results.json",
74
+ IndexTestResultsByHistoryId = "index-test-results-by-history-id.json",
75
+ IndexTestResultsByTestCase = "index-test-results-by-test-case.json",
76
+ IndexLatestEnvTestResultsByHistoryId = "index-latest-env-test-results-by-history-id.json",
77
+ IndexAttachmentsByFixture = "index-attachments-by-fixture.json",
78
+ IndexFixturesByTestResult = "index-fixtures-by-test-result.json",
79
+ IndexKnownByHistoryId = "index-known-by-history-id.json",
80
+ QualityGateResultsByRules = "quality-gate-results-by-rules.json"
30
81
  }
package/dist/store.js CHANGED
@@ -1 +1,19 @@
1
- export {};
1
+ export var AllureStoreDumpFiles;
2
+ (function (AllureStoreDumpFiles) {
3
+ AllureStoreDumpFiles["TestResults"] = "test-results.json";
4
+ AllureStoreDumpFiles["TestCases"] = "test-cases.json";
5
+ AllureStoreDumpFiles["Fixtures"] = "fixtures.json";
6
+ AllureStoreDumpFiles["GlobalErrors"] = "global-errors.json";
7
+ AllureStoreDumpFiles["GlobalAttachments"] = "global-attachments.json";
8
+ AllureStoreDumpFiles["Attachments"] = "attachments.json";
9
+ AllureStoreDumpFiles["Environments"] = "environments.json";
10
+ AllureStoreDumpFiles["ReportVariables"] = "report-variables.json";
11
+ AllureStoreDumpFiles["IndexAttachmentsByTestResults"] = "index-attachments-by-test-results.json";
12
+ AllureStoreDumpFiles["IndexTestResultsByHistoryId"] = "index-test-results-by-history-id.json";
13
+ AllureStoreDumpFiles["IndexTestResultsByTestCase"] = "index-test-results-by-test-case.json";
14
+ AllureStoreDumpFiles["IndexLatestEnvTestResultsByHistoryId"] = "index-latest-env-test-results-by-history-id.json";
15
+ AllureStoreDumpFiles["IndexAttachmentsByFixture"] = "index-attachments-by-fixture.json";
16
+ AllureStoreDumpFiles["IndexFixturesByTestResult"] = "index-fixtures-by-test-result.json";
17
+ AllureStoreDumpFiles["IndexKnownByHistoryId"] = "index-known-by-history-id.json";
18
+ AllureStoreDumpFiles["QualityGateResultsByRules"] = "quality-gate-results-by-rules.json";
19
+ })(AllureStoreDumpFiles || (AllureStoreDumpFiles = {}));
@@ -0,0 +1,3 @@
1
+ import type { TestResult } from "@allurereport/core-api";
2
+ import type { SummaryTestResult } from "../plugin.js";
3
+ export declare const convertToSummaryTestResult: (tr: TestResult) => SummaryTestResult;
@@ -0,0 +1,6 @@
1
+ export const convertToSummaryTestResult = (tr) => ({
2
+ id: tr.id,
3
+ name: tr.name,
4
+ status: tr.status,
5
+ duration: tr.duration,
6
+ });
@@ -8,3 +8,5 @@ export declare const preciseTreeLabels: <T = TestResult>(labelNames: string[], t
8
8
  export declare const filterTree: <L, G>(tree: TreeData<L, G>, predicate: (leaf: TreeLeaf<L>) => boolean) => TreeData<L, G>;
9
9
  export declare const sortTree: <L, G>(tree: TreeData<L, G>, comparator: Comparator<TreeLeaf<L>>) => TreeData<L, G>;
10
10
  export declare const transformTree: <L, G>(tree: TreeData<L, G>, transformer: (leaf: TreeLeaf<L>, idx: number) => TreeLeaf<L>) => TreeData<L, G>;
11
+ export declare const createTreeByTitlePath: <T = TestResult, L = DefaultTreeLeaf, G = DefaultTreeGroup>(data: T[], leafFactory?: (item: T) => TreeLeaf<L>, groupFactory?: (parentGroup: string | undefined, groupClassifier: string) => TreeGroup<G>, addLeafToGroup?: (group: TreeGroup<G>, leaf: TreeLeaf<L>) => void) => TreeData<L, G>;
12
+ export declare const createTreeByLabelsAndTitlePath: <T = TestResult, L = DefaultTreeLeaf, G = DefaultTreeGroup>(data: T[], labelNames?: string[], leafFactory?: (item: T) => TreeLeaf<L>, groupFactory?: (parentGroup: string | undefined, groupClassifier: string) => TreeGroup<G>, addLeafToGroup?: (group: TreeGroup<G>, leaf: TreeLeaf<L>) => void) => TreeData<L, G>;
@@ -197,3 +197,58 @@ export const transformTree = (tree, transformer) => {
197
197
  transformGroupLeaves(root);
198
198
  return tree;
199
199
  };
200
+ export const createTreeByTitlePath = (data, leafFactory, groupFactory, addLeafToGroup = () => { }) => {
201
+ const leafFactoryFn = leafFactory ??
202
+ ((tr) => {
203
+ const { id, name, status, duration } = tr;
204
+ return {
205
+ nodeId: id,
206
+ name,
207
+ status,
208
+ duration,
209
+ };
210
+ });
211
+ const groupFactoryFn = groupFactory ??
212
+ ((parentId, groupClassifier) => ({
213
+ nodeId: md5((parentId ? `${parentId}.` : "") + groupClassifier),
214
+ name: groupClassifier,
215
+ statistic: emptyStatistic(),
216
+ }));
217
+ return createTree(data, (item) => (item.titlePath ?? []).map((segment) => [segment]), leafFactoryFn, groupFactoryFn, addLeafToGroup);
218
+ };
219
+ const byLabelsAndTitlePath = (item, labelNames) => {
220
+ const leaves = [];
221
+ for (const labelName of labelNames) {
222
+ const values = item.labels.filter((label) => label.name === labelName).map((label) => label.value ?? "");
223
+ if (!values.length) {
224
+ continue;
225
+ }
226
+ leaves.push(values);
227
+ }
228
+ const titlePath = item.titlePath;
229
+ if (Array.isArray(titlePath) && titlePath.length > 0) {
230
+ for (const segment of titlePath) {
231
+ leaves.push([segment]);
232
+ }
233
+ }
234
+ return leaves;
235
+ };
236
+ export const createTreeByLabelsAndTitlePath = (data, labelNames = [], leafFactory, groupFactory, addLeafToGroup = () => { }) => {
237
+ const leafFactoryFn = leafFactory ??
238
+ ((tr) => {
239
+ const { id, name, status, duration } = tr;
240
+ return {
241
+ nodeId: id,
242
+ name,
243
+ status,
244
+ duration,
245
+ };
246
+ });
247
+ const groupFactoryFn = groupFactory ??
248
+ ((parentId, groupClassifier) => ({
249
+ nodeId: md5((parentId ? `${parentId}.` : "") + groupClassifier),
250
+ name: groupClassifier,
251
+ statistic: emptyStatistic(),
252
+ }));
253
+ return createTree(data, (item) => byLabelsAndTitlePath(item, labelNames), leafFactoryFn, groupFactoryFn, addLeafToGroup);
254
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@allurereport/plugin-api",
3
- "version": "3.0.0-beta.9",
3
+ "version": "3.0.0",
4
4
  "description": "Allure Plugin API",
5
5
  "keywords": [
6
6
  "allure"
@@ -26,7 +26,7 @@
26
26
  "test": "rimraf ./out && vitest run"
27
27
  },
28
28
  "dependencies": {
29
- "@allurereport/core-api": "3.0.0-beta.9"
29
+ "@allurereport/core-api": "3.0.0"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@stylistic/eslint-plugin": "^2.6.1",
@@ -34,9 +34,9 @@
34
34
  "@types/node": "^20.17.9",
35
35
  "@typescript-eslint/eslint-plugin": "^8.0.0",
36
36
  "@typescript-eslint/parser": "^8.0.0",
37
- "@vitest/runner": "^2.1.8",
38
- "@vitest/snapshot": "^2.1.8",
39
- "allure-vitest": "^3.0.9",
37
+ "@vitest/runner": "^2.1.9",
38
+ "@vitest/snapshot": "^2.1.9",
39
+ "allure-vitest": "^3.3.3",
40
40
  "eslint": "^8.57.0",
41
41
  "eslint-config-prettier": "^9.1.0",
42
42
  "eslint-plugin-import": "^2.29.1",
@@ -46,6 +46,6 @@
46
46
  "eslint-plugin-prefer-arrow": "^1.2.3",
47
47
  "rimraf": "^6.0.1",
48
48
  "typescript": "^5.6.3",
49
- "vitest": "^2.1.8"
49
+ "vitest": "^2.1.9"
50
50
  }
51
51
  }