@allurereport/plugin-api 3.2.0 → 3.3.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/dist/config.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { DefaultLabelsConfig, EnvironmentsConfig, ReportVariables } from "@allurereport/core-api";
1
+ import type { CategoriesConfig, DefaultLabelsConfig, EnvironmentsConfig, ReportVariables } from "@allurereport/core-api";
2
2
  import type { PluginDescriptor } from "./plugin.js";
3
3
  import type { QualityGateConfig } from "./qualityGate.js";
4
4
  export interface Config {
@@ -10,7 +10,7 @@ export interface Config {
10
10
  historyLimit?: number;
11
11
  knownIssuesPath?: string;
12
12
  defaultLabels?: DefaultLabelsConfig;
13
- stage?: string;
13
+ dump?: string;
14
14
  environment?: string;
15
15
  environments?: EnvironmentsConfig;
16
16
  variables?: ReportVariables;
@@ -20,5 +20,6 @@ export interface Config {
20
20
  allureService?: {
21
21
  accessToken?: string;
22
22
  };
23
+ categories?: CategoriesConfig;
23
24
  }
24
25
  export declare const defineConfig: (allureConfig: Config) => Config;
package/dist/plugin.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { AttachmentLink, CiDescriptor, Statistic, TestError, TestResult, TestStatus } from "@allurereport/core-api";
1
+ import type { AllureHistory, AttachmentLink, CategoryDefinition, CiDescriptor, Statistic, TestError, TestResult, TestStatus } from "@allurereport/core-api";
2
2
  import type { QualityGateValidationResult } from "./qualityGate.js";
3
3
  import type { ResultFile } from "./resultFile.js";
4
4
  import type { AllureStore } from "./store.js";
@@ -26,6 +26,8 @@ export interface PluginContext {
26
26
  reportUrl?: string;
27
27
  output: string;
28
28
  ci?: CiDescriptor;
29
+ categories?: CategoryDefinition[];
30
+ history?: AllureHistory;
29
31
  }
30
32
  export type SummaryTestResult = Pick<TestResult, "name" | "id" | "status" | "duration">;
31
33
  export interface PluginSummary {
package/dist/store.d.ts CHANGED
@@ -15,7 +15,7 @@ export interface AllureStore {
15
15
  allHistoryDataPoints: () => Promise<HistoryDataPoint[]>;
16
16
  allHistoryDataPointsByEnvironment: (environment: string) => Promise<HistoryDataPoint[]>;
17
17
  allKnownIssues: () => Promise<KnownTestFailure[]>;
18
- allNewTestResults: (filter?: TestResultFilter) => Promise<TestResult[]>;
18
+ allNewTestResults: (filter?: TestResultFilter, history?: HistoryDataPoint[]) => Promise<TestResult[]>;
19
19
  qualityGateResults: () => Promise<QualityGateValidationResult[]>;
20
20
  qualityGateResultsByEnv: () => Promise<Record<string, QualityGateValidationResult[]>>;
21
21
  globalExitCode: () => Promise<ExitCode | undefined>;
@@ -1,3 +1,13 @@
1
- import type { TestResult } from "@allurereport/core-api";
2
- import type { SummaryTestResult } from "../plugin.js";
1
+ import { type AllureHistory, type CiDescriptor, type TestResult } from "@allurereport/core-api";
2
+ import type { PluginSummary, SummaryTestResult } from "../plugin.js";
3
+ import type { AllureStore } from "../store.js";
3
4
  export declare const convertToSummaryTestResult: (tr: TestResult) => SummaryTestResult;
5
+ export declare const createPluginSummary: (params: {
6
+ filter?: (testResult: TestResult) => boolean;
7
+ name: string;
8
+ plugin: string;
9
+ store: AllureStore;
10
+ history?: AllureHistory;
11
+ ci?: CiDescriptor;
12
+ meta: Record<string, any>;
13
+ }) => Promise<PluginSummary>;
@@ -1,6 +1,31 @@
1
+ import { getWorstStatus } from "@allurereport/core-api";
1
2
  export const convertToSummaryTestResult = (tr) => ({
2
3
  id: tr.id,
3
4
  name: tr.name,
4
5
  status: tr.status,
5
6
  duration: tr.duration,
6
7
  });
8
+ export const createPluginSummary = async (params) => {
9
+ const { name, filter, plugin, store, history, meta } = params;
10
+ const allTrs = await store.allTestResults({ filter });
11
+ const mainBranchHistory = (await history?.readHistory?.({ branch: "" })) ?? [];
12
+ const newTrs = await store.allNewTestResults(filter, mainBranchHistory);
13
+ const retryTrs = allTrs.filter((tr) => !!tr?.retries?.length);
14
+ const flakyTrs = allTrs.filter((tr) => !!tr?.flaky);
15
+ const duration = allTrs.reduce((acc, { duration: trDuration = 0 }) => acc + trDuration, 0);
16
+ const worstStatus = getWorstStatus(allTrs.map(({ status }) => status));
17
+ const createdAt = allTrs.reduce((acc, { stop }) => Math.max(acc, stop || 0), 0);
18
+ const summary = {
19
+ stats: await store.testsStatistic(filter),
20
+ status: worstStatus ?? "passed",
21
+ newTests: newTrs.map(convertToSummaryTestResult),
22
+ flakyTests: flakyTrs.map(convertToSummaryTestResult),
23
+ retryTests: retryTrs.map(convertToSummaryTestResult),
24
+ name,
25
+ duration,
26
+ createdAt,
27
+ plugin,
28
+ meta,
29
+ };
30
+ return summary;
31
+ };
@@ -1,4 +1,4 @@
1
- import { findByLabelName, } from "@allurereport/core-api";
1
+ import { createDictionary, findByLabelName, } from "@allurereport/core-api";
2
2
  import { emptyStatistic } from "@allurereport/core-api";
3
3
  import { md5 } from "./misc.js";
4
4
  const addLeaf = (node, nodeId) => {
@@ -20,7 +20,7 @@ const addGroup = (node, nodeId) => {
20
20
  node.groups.push(nodeId);
21
21
  };
22
22
  const createTree = (data, classifier, leafFactory, groupFactory, addLeafToGroup = () => { }) => {
23
- const groupsByClassifier = {};
23
+ const groupsByClassifier = createDictionary();
24
24
  const leavesById = {};
25
25
  const groupsById = {};
26
26
  const root = { groups: [], leaves: [] };
@@ -34,21 +34,26 @@ const createTree = (data, classifier, leafFactory, groupFactory, addLeafToGroup
34
34
  break;
35
35
  }
36
36
  parentGroups = layer.flatMap((group) => {
37
- return parentGroups.map((parentGroup) => {
37
+ return parentGroups.flatMap((parentGroup) => {
38
38
  const parentId = "nodeId" in parentGroup ? parentGroup.nodeId : "";
39
39
  if (groupsByClassifier[parentId] === undefined) {
40
- groupsByClassifier[parentId] = {};
40
+ groupsByClassifier[parentId] = createDictionary();
41
41
  }
42
- if (groupsByClassifier[parentId][group] === undefined ||
43
- typeof groupsByClassifier[parentId][group] === "function") {
42
+ if (groupsByClassifier[parentId][group] === undefined) {
44
43
  const newGroup = groupFactory(parentId, group);
44
+ if (!newGroup || typeof newGroup !== "object" || typeof newGroup.nodeId !== "string") {
45
+ return [];
46
+ }
45
47
  groupsByClassifier[parentId][group] = newGroup;
46
48
  groupsById[newGroup.nodeId] = newGroup;
47
49
  }
48
50
  const currentGroup = groupsByClassifier[parentId][group];
51
+ if (!currentGroup || typeof currentGroup !== "object") {
52
+ return [];
53
+ }
49
54
  addGroup(parentGroup, currentGroup.nodeId);
50
55
  addLeafToGroup(currentGroup, leaf);
51
- return currentGroup;
56
+ return [currentGroup];
52
57
  });
53
58
  });
54
59
  }
@@ -63,7 +68,9 @@ const createTree = (data, classifier, leafFactory, groupFactory, addLeafToGroup
63
68
  };
64
69
  };
65
70
  export const byLabels = (item, labelNames) => {
66
- return labelNames.map((labelName) => item.labels.filter((label) => labelName === label.name).map((label) => label.value ?? "__unknown") ?? []);
71
+ return labelNames
72
+ .map((labelName) => item.labels.filter((label) => labelName === label.name).map((label) => label.value ?? "__unknown") ?? [])
73
+ .filter((layer) => layer.length > 0);
67
74
  };
68
75
  export const filterTreeLabels = (data, labelNames) => {
69
76
  return [...labelNames]
@@ -110,7 +117,15 @@ export const createTreeByCategories = (data, leafFactory, groupFactory, addLeafT
110
117
  return createTree(data, (item) => byCategories(item), leafFactoryFn, groupFactoryFn, addLeafToGroup);
111
118
  };
112
119
  export const byCategories = (item) => {
113
- return [item.categories?.map((category) => category.name)];
120
+ const categories = item.categories ?? [];
121
+ const result = [];
122
+ for (const category of categories) {
123
+ result.push([category.name]);
124
+ }
125
+ if (item.error?.message) {
126
+ result.push([item.error?.message]);
127
+ }
128
+ return result;
114
129
  };
115
130
  export const preciseTreeLabels = (labelNames, trs, labelNamesAccessor = (tr) => tr.labels.map(({ name }) => name)) => {
116
131
  const result = new Set();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@allurereport/plugin-api",
3
- "version": "3.2.0",
3
+ "version": "3.3.1",
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.2.0"
29
+ "@allurereport/core-api": "3.3.1"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@stylistic/eslint-plugin": "^2.6.1",