@allurereport/plugin-api 3.0.0-beta.3
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 +27 -0
- package/dist/config.d.ts +11 -0
- package/dist/config.js +3 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +7 -0
- package/dist/plugin.d.ts +34 -0
- package/dist/plugin.js +1 -0
- package/dist/qualityGate.d.ts +44 -0
- package/dist/qualityGate.js +1 -0
- package/dist/resultFile.d.ts +12 -0
- package/dist/resultFile.js +1 -0
- package/dist/store.d.ts +30 -0
- package/dist/store.js +1 -0
- package/dist/utils/misc.d.ts +1 -0
- package/dist/utils/misc.js +2 -0
- package/dist/utils/tree.d.ts +2 -0
- package/dist/utils/tree.js +78 -0
- package/package.json +48 -0
package/README.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Plugin API
|
|
2
|
+
|
|
3
|
+
> Collection of interfaces for Allure plugins
|
|
4
|
+
|
|
5
|
+
[<img src="https://allurereport.org/public/img/allure-report.svg" height="85px" alt="Allure Report logo" align="right" />](https://allurereport.org "Allure Report")
|
|
6
|
+
|
|
7
|
+
- Learn more about Allure Report at https://allurereport.org
|
|
8
|
+
- 📚 [Documentation](https://allurereport.org/docs/) – discover official documentation for Allure Report
|
|
9
|
+
- ❓ [Questions and Support](https://github.com/orgs/allure-framework/discussions/categories/questions-support) – get help from the team and community
|
|
10
|
+
- 📢 [Official announcements](https://github.com/orgs/allure-framework/discussions/categories/announcements) – be in touch with the latest updates
|
|
11
|
+
- 💬 [General Discussion ](https://github.com/orgs/allure-framework/discussions/categories/general-discussion) – engage in casual conversations, share insights and ideas with the community
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Overview
|
|
16
|
+
|
|
17
|
+
The interfaces in the package describe the entities used for building Allure Plugins.
|
|
18
|
+
|
|
19
|
+
## Install
|
|
20
|
+
|
|
21
|
+
Use your favorite package manager to install the package:
|
|
22
|
+
|
|
23
|
+
```shell
|
|
24
|
+
npm add @allurereport/plugin-api
|
|
25
|
+
yarn add @allurereport/plugin-api
|
|
26
|
+
pnpm add @allurereport/plugin-api
|
|
27
|
+
```
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { PluginDescriptor } from "./plugin.js";
|
|
2
|
+
import type { QualityGateConfig } from "./qualityGate.js";
|
|
3
|
+
export interface Config {
|
|
4
|
+
name?: string;
|
|
5
|
+
output?: string;
|
|
6
|
+
historyPath?: string;
|
|
7
|
+
knownIssuesPath?: string;
|
|
8
|
+
qualityGate?: QualityGateConfig;
|
|
9
|
+
plugins?: Record<string, PluginDescriptor>;
|
|
10
|
+
}
|
|
11
|
+
export declare const defineConfig: (allureConfig: Config) => Promise<Config>;
|
package/dist/config.js
ADDED
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
package/dist/plugin.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { AllureStore } from "./store.js";
|
|
2
|
+
export interface PluginDescriptor {
|
|
3
|
+
import?: string;
|
|
4
|
+
enabled?: boolean;
|
|
5
|
+
options?: Record<string, any>;
|
|
6
|
+
}
|
|
7
|
+
export interface ReportFiles {
|
|
8
|
+
addFile(path: string, data: Buffer): Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
export interface PluginState {
|
|
11
|
+
set(key: string, value: any): Promise<void>;
|
|
12
|
+
get(key: string): Promise<void>;
|
|
13
|
+
unset(key: string): Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
export interface PluginContext {
|
|
16
|
+
state: PluginState;
|
|
17
|
+
allureVersion: string;
|
|
18
|
+
reportUuid: string;
|
|
19
|
+
reportName: string;
|
|
20
|
+
reportFiles: ReportFiles;
|
|
21
|
+
}
|
|
22
|
+
export interface BatchOptions {
|
|
23
|
+
maxTimeout?: number;
|
|
24
|
+
}
|
|
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;
|
|
29
|
+
}
|
|
30
|
+
export interface Plugin {
|
|
31
|
+
start?(context: PluginContext, store: AllureStore, realtime: Realtime): Promise<void>;
|
|
32
|
+
update?(context: PluginContext, store: AllureStore): Promise<void>;
|
|
33
|
+
done?(context: PluginContext, store: AllureStore): Promise<void>;
|
|
34
|
+
}
|
package/dist/plugin.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,44 @@
|
|
|
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;
|
|
28
|
+
export type QualityGateValidationResult = {
|
|
29
|
+
success: boolean;
|
|
30
|
+
rule: string;
|
|
31
|
+
meta?: QualityGateRulesMeta;
|
|
32
|
+
expected?: number;
|
|
33
|
+
actual?: number;
|
|
34
|
+
message?: string;
|
|
35
|
+
};
|
|
36
|
+
export interface QualityGateValidator {
|
|
37
|
+
validate(store: AllureStore): Promise<QualityGateValidationResult>;
|
|
38
|
+
}
|
|
39
|
+
export type QualityGateValidatorConstructor = new (limit: number, meta?: QualityGateRulesMeta) => QualityGateValidator;
|
|
40
|
+
export type QualityGateConfig = {
|
|
41
|
+
rules?: QualityGateRules;
|
|
42
|
+
enforce?: QualityGateEnforceConfig[];
|
|
43
|
+
validators?: Record<string, QualityGateValidatorConstructor>;
|
|
44
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import "node:fs/promises";
|
|
2
|
+
import { Readable } from "node:stream";
|
|
3
|
+
export interface ResultFile {
|
|
4
|
+
readContent: <T>(transform: (stream: Readable) => Promise<T | undefined>) => Promise<T | undefined>;
|
|
5
|
+
getOriginalFileName: () => string;
|
|
6
|
+
getContentType: () => string | undefined;
|
|
7
|
+
getContentLength: () => number | undefined;
|
|
8
|
+
asJson: <T>() => Promise<T | undefined>;
|
|
9
|
+
asUtf8String: () => Promise<string | undefined>;
|
|
10
|
+
asBuffer: () => Promise<Buffer | undefined>;
|
|
11
|
+
writeTo: (path: string) => Promise<void>;
|
|
12
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import "node:fs/promises";
|
package/dist/store.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { AttachmentLink, HistoryDataPoint, HistoryTestResult, KnownTestFailure, Statistic, TestCase, TestFixtureResult, TestResult } from "@allurereport/core-api";
|
|
2
|
+
import { ResultFile } from "./resultFile.js";
|
|
3
|
+
export interface AllureStore {
|
|
4
|
+
allTestCases: () => Promise<TestCase[]>;
|
|
5
|
+
allTestResults: (options?: {
|
|
6
|
+
includeHidden: boolean;
|
|
7
|
+
}) => Promise<TestResult[]>;
|
|
8
|
+
allAttachments: () => Promise<AttachmentLink[]>;
|
|
9
|
+
allMetadata: () => Promise<Record<string, any>>;
|
|
10
|
+
allFixtures: () => Promise<TestFixtureResult[]>;
|
|
11
|
+
allHistoryDataPoints: () => Promise<HistoryDataPoint[]>;
|
|
12
|
+
allKnownIssues: () => Promise<KnownTestFailure[]>;
|
|
13
|
+
testCaseById: (tcId: string) => Promise<TestCase | undefined>;
|
|
14
|
+
testResultById: (trId: string) => Promise<TestResult | undefined>;
|
|
15
|
+
attachmentById: (attachmentId: string) => Promise<AttachmentLink | undefined>;
|
|
16
|
+
attachmentContentById: (attachmentId: string) => Promise<ResultFile | undefined>;
|
|
17
|
+
metadataByKey: <T>(key: string) => Promise<T | undefined>;
|
|
18
|
+
testResultsByTcId: (tcId: string) => Promise<TestResult[]>;
|
|
19
|
+
attachmentsByTrId: (trId: string) => Promise<AttachmentLink[]>;
|
|
20
|
+
retriesByTrId: (trId: string) => Promise<TestResult[]>;
|
|
21
|
+
historyByTrId: (trId: string) => Promise<HistoryTestResult[]>;
|
|
22
|
+
fixturesByTrId: (trId: string) => Promise<TestFixtureResult[]>;
|
|
23
|
+
failedTestResults: () => Promise<TestResult[]>;
|
|
24
|
+
unknownFailedTestResults: () => Promise<TestResult[]>;
|
|
25
|
+
testResultsByLabel: (labelName: string) => Promise<{
|
|
26
|
+
_: TestResult[];
|
|
27
|
+
[x: string]: TestResult[];
|
|
28
|
+
}>;
|
|
29
|
+
testsStatistic: (filter?: (testResult: TestResult) => boolean) => Promise<Statistic>;
|
|
30
|
+
}
|
package/dist/store.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const md5: (data: string) => string;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { emptyStatistic, incrementStatistic } from "@allurereport/core-api";
|
|
2
|
+
import { md5 } from "./misc.js";
|
|
3
|
+
const addLeaf = (node, nodeId) => {
|
|
4
|
+
if (node.leaves === undefined) {
|
|
5
|
+
node.leaves = [];
|
|
6
|
+
}
|
|
7
|
+
if (node.leaves.find((value) => value === nodeId)) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
node.leaves.push(nodeId);
|
|
11
|
+
};
|
|
12
|
+
const addGroup = (node, nodeId) => {
|
|
13
|
+
if (node.groups === undefined) {
|
|
14
|
+
node.groups = [];
|
|
15
|
+
}
|
|
16
|
+
if (node.groups.find((value) => value === nodeId)) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
node.groups.push(nodeId);
|
|
20
|
+
};
|
|
21
|
+
const createTree = (data, classifier, leafFactory, groupFactory, addLeafToGroup = () => { }) => {
|
|
22
|
+
const groupsByClassifier = {};
|
|
23
|
+
const leavesById = {};
|
|
24
|
+
const groupsById = {};
|
|
25
|
+
const root = { groups: [], leaves: [] };
|
|
26
|
+
for (const item of data) {
|
|
27
|
+
const leaf = leafFactory(item);
|
|
28
|
+
leavesById[leaf.nodeId] = leaf;
|
|
29
|
+
const itemGroups = classifier(item);
|
|
30
|
+
let parentGroups = [root];
|
|
31
|
+
for (const layer of itemGroups) {
|
|
32
|
+
if (layer.length === 0) {
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
parentGroups = layer.flatMap((group) => {
|
|
36
|
+
return parentGroups.map((parentGroup) => {
|
|
37
|
+
const parentId = "nodeId" in parentGroup ? parentGroup.nodeId : "";
|
|
38
|
+
if (groupsByClassifier[parentId] === undefined) {
|
|
39
|
+
groupsByClassifier[parentId] = {};
|
|
40
|
+
}
|
|
41
|
+
if (groupsByClassifier[parentId][group] === undefined) {
|
|
42
|
+
const newGroup = groupFactory(parentId, group);
|
|
43
|
+
groupsByClassifier[parentId][group] = newGroup;
|
|
44
|
+
groupsById[newGroup.nodeId] = newGroup;
|
|
45
|
+
}
|
|
46
|
+
const currentGroup = groupsByClassifier[parentId][group];
|
|
47
|
+
addGroup(parentGroup, currentGroup.nodeId);
|
|
48
|
+
addLeafToGroup(currentGroup, leaf);
|
|
49
|
+
return currentGroup;
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
parentGroups.forEach((parentGroup) => addLeaf(parentGroup, leaf.nodeId));
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
root,
|
|
57
|
+
groupsById,
|
|
58
|
+
leavesById,
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
const byLabels = (item, labelNames) => {
|
|
62
|
+
return labelNames.map((labelName) => item.labels.filter((label) => labelName === label.name).map((label) => label.value ?? "__unknown") ?? []);
|
|
63
|
+
};
|
|
64
|
+
export const createTreeByLabels = (data, labelNames) => {
|
|
65
|
+
return createTree(data, (item) => byLabels(item, labelNames), ({ id, name, status, duration, flaky, retries }) => ({
|
|
66
|
+
nodeId: id,
|
|
67
|
+
name,
|
|
68
|
+
status,
|
|
69
|
+
duration,
|
|
70
|
+
flaky,
|
|
71
|
+
}), (parentId, groupClassifier) => ({
|
|
72
|
+
nodeId: md5((parentId ? `${parentId}.` : "") + groupClassifier),
|
|
73
|
+
name: groupClassifier,
|
|
74
|
+
statistic: emptyStatistic(),
|
|
75
|
+
}), (group, leaf) => {
|
|
76
|
+
incrementStatistic(group.statistic, leaf.status);
|
|
77
|
+
});
|
|
78
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@allurereport/plugin-api",
|
|
3
|
+
"version": "3.0.0-beta.3",
|
|
4
|
+
"description": "Allure Plugin API",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"allure"
|
|
7
|
+
],
|
|
8
|
+
"repository": "https://github.com/allure-framework/allure3",
|
|
9
|
+
"license": "Apache-2.0",
|
|
10
|
+
"author": "Qameta Software",
|
|
11
|
+
"type": "module",
|
|
12
|
+
"exports": {
|
|
13
|
+
".": "./dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"main": "./dist/index.js",
|
|
16
|
+
"module": "./dist/index.js",
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"files": [
|
|
19
|
+
"dist"
|
|
20
|
+
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "run clean && tsc --project ./tsconfig.json",
|
|
23
|
+
"clean": "rimraf ./dist",
|
|
24
|
+
"test": "rimraf ./out && vitest run"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@allurereport/core-api": "3.0.0-beta.3"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@stylistic/eslint-plugin": "^2.6.1",
|
|
31
|
+
"@types/eslint": "^8.56.11",
|
|
32
|
+
"@types/node": "^20.17.9",
|
|
33
|
+
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
34
|
+
"@typescript-eslint/parser": "^8.0.0",
|
|
35
|
+
"@vitest/runner": "^2.1.8",
|
|
36
|
+
"allure-vitest": "^3.0.7",
|
|
37
|
+
"eslint": "^8.57.0",
|
|
38
|
+
"eslint-config-prettier": "^9.1.0",
|
|
39
|
+
"eslint-plugin-import": "^2.29.1",
|
|
40
|
+
"eslint-plugin-jsdoc": "^50.0.0",
|
|
41
|
+
"eslint-plugin-n": "^17.10.1",
|
|
42
|
+
"eslint-plugin-no-null": "^1.0.2",
|
|
43
|
+
"eslint-plugin-prefer-arrow": "^1.2.3",
|
|
44
|
+
"rimraf": "^6.0.1",
|
|
45
|
+
"typescript": "^5.6.3",
|
|
46
|
+
"vitest": "^2.1.8"
|
|
47
|
+
}
|
|
48
|
+
}
|