@allurereport/plugin-awesome 3.0.1 → 3.2.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.
@@ -1,3 +1,6 @@
1
+ import MarkdownIt from "markdown-it";
2
+ const md = new MarkdownIt();
3
+ const markdownToHtml = (value) => (value ? md.render(value) : undefined);
1
4
  const mapLabelsByName = (labels) => {
2
5
  return labels.reduce((acc, { name, value }) => {
3
6
  acc[name] = acc[name] || [];
@@ -28,6 +31,7 @@ export const convertTestResult = (tr) => {
28
31
  steps: tr.steps,
29
32
  error: tr.error,
30
33
  testCase: tr.testCase,
34
+ descriptionHtml: tr.descriptionHtml ?? markdownToHtml(tr.description),
31
35
  environment: tr.environment,
32
36
  setup: [],
33
37
  teardown: [],
@@ -1,7 +1,7 @@
1
- import type { AllureStore } from "@allurereport/plugin-api";
1
+ import type { AwesomeTestResult } from "@allurereport/web-awesome";
2
2
  import type { AwesomeOptions } from "./model.js";
3
3
  type Writer = {
4
4
  writeWidget(fileName: string, data: any): Promise<void>;
5
5
  };
6
- export declare const generateTimeline: (writer: Writer, store: AllureStore, options: AwesomeOptions) => Promise<void>;
6
+ export declare const generateTimeline: (writer: Writer, trs: AwesomeTestResult[], options: AwesomeOptions) => Promise<void>;
7
7
  export {};
@@ -1,16 +1,12 @@
1
- import { hasLabels } from "@allurereport/web-commons";
2
1
  const DEFAULT_MIN_DURATION = 1;
3
- const HOST_LABEL = "host";
4
- const THREAD_LABEL = "thread";
5
2
  const DEFAULT_TIMELINE_OPTIONS = {
6
3
  minDuration: DEFAULT_MIN_DURATION,
7
4
  };
8
- export const generateTimeline = async (writer, store, options) => {
5
+ export const generateTimeline = async (writer, trs, options) => {
9
6
  const { timeline = DEFAULT_TIMELINE_OPTIONS } = options;
10
7
  const { minDuration = DEFAULT_MIN_DURATION } = timeline;
11
- const testResults = await store.allTestResults({ includeHidden: true });
12
8
  const result = [];
13
- for (const test of testResults) {
9
+ for (const test of trs) {
14
10
  const hasStart = Number.isInteger(test.start);
15
11
  const hasStop = Number.isInteger(test.stop);
16
12
  if (!hasStart || !hasStop) {
@@ -20,7 +16,8 @@ export const generateTimeline = async (writer, store, options) => {
20
16
  if (duration < minDuration) {
21
17
  continue;
22
18
  }
23
- if (!hasLabels(test, [HOST_LABEL, THREAD_LABEL])) {
19
+ const { host, thread } = test.groupedLabels;
20
+ if (!host?.length || !thread?.length) {
24
21
  continue;
25
22
  }
26
23
  result.push({
@@ -29,10 +26,10 @@ export const generateTimeline = async (writer, store, options) => {
29
26
  name: test.name,
30
27
  status: test.status,
31
28
  hidden: test.hidden,
32
- labels: test.labels,
29
+ host: host[0],
30
+ thread: thread[0],
33
31
  environment: test.environment,
34
32
  start: test.start,
35
- stop: test.stop,
36
33
  duration,
37
34
  });
38
35
  }
@@ -1,10 +1,10 @@
1
1
  import { type AttachmentLink, type EnvironmentItem, type Statistic, type TestEnvGroup, type TestError, type TestResult } from "@allurereport/core-api";
2
- import type { AllureStore, ExitCode, PluginContext, QualityGateValidationResult, ReportFiles, ResultFile, TestResultFilter } from "@allurereport/plugin-api";
2
+ import type { AllureStore, ExitCode, PluginContext, QualityGateValidationResult, ReportFiles, ResultFile } from "@allurereport/plugin-api";
3
3
  import type { AwesomeTestResult } from "@allurereport/web-awesome";
4
4
  import type { AwesomeOptions, TemplateManifest } from "./model.js";
5
5
  import type { AwesomeDataWriter, ReportFile } from "./writer.js";
6
6
  export declare const readTemplateManifest: (singleFileMode?: boolean) => Promise<TemplateManifest>;
7
- export declare const generateTestResults: (writer: AwesomeDataWriter, store: AllureStore, trs: TestResult[], filter?: TestResultFilter) => Promise<AwesomeTestResult[]>;
7
+ export declare const generateTestResults: (writer: AwesomeDataWriter, store: AllureStore, trs: TestResult[]) => Promise<AwesomeTestResult[]>;
8
8
  export declare const generateTestCases: (writer: AwesomeDataWriter, trs: AwesomeTestResult[]) => Promise<void>;
9
9
  export declare const generateTestEnvGroups: (writer: AwesomeDataWriter, groups: TestEnvGroup[]) => Promise<void>;
10
10
  export declare const generateNav: (writer: AwesomeDataWriter, trs: AwesomeTestResult[], filename?: string) => Promise<void>;
@@ -27,7 +27,7 @@ export declare const generateGlobals: (writer: AwesomeDataWriter, payload: {
27
27
  globalErrors?: TestError[];
28
28
  contentFunction: (id: string) => Promise<ResultFile | undefined>;
29
29
  }) => Promise<void>;
30
- export declare const generateQualityGateResults: (writer: AwesomeDataWriter, qualityGateResults?: QualityGateValidationResult[]) => Promise<void>;
30
+ export declare const generateQualityGateResults: (writer: AwesomeDataWriter, qualityGateResults?: Record<string, QualityGateValidationResult[]>) => Promise<void>;
31
31
  export declare const generateStaticFiles: (payload: AwesomeOptions & {
32
32
  id: string;
33
33
  allureVersion: string;
@@ -37,3 +37,4 @@ export declare const generateStaticFiles: (payload: AwesomeOptions & {
37
37
  reportName: string;
38
38
  }) => Promise<void>;
39
39
  export declare const generateAllCharts: (writer: AwesomeDataWriter, store: AllureStore, options: AwesomeOptions, context: PluginContext) => Promise<void>;
40
+ export declare const generateTreeFilters: (writer: AwesomeDataWriter, testResults: AwesomeTestResult[]) => Promise<void>;
@@ -16,6 +16,9 @@ const template = `<!DOCTYPE html>
16
16
  <title> {{ reportName }} </title>
17
17
  <link rel="icon" href="data:image/svg+xml,%3Csvg width='32' height='32' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M22.232 4.662a3.6 3.6 0 0 1 5.09.035c2.855 2.894 4.662 6.885 4.662 11.295a3.6 3.6 0 0 1-7.2 0c0-2.406-.981-4.61-2.587-6.24a3.6 3.6 0 0 1 .035-5.09Z' fill='url(%23a)'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M12.392 3.6a3.6 3.6 0 0 1 3.6-3.6c4.41 0 8.401 1.807 11.296 4.662a3.6 3.6 0 1 1-5.056 5.126C20.602 8.18 18.398 7.2 15.992 7.2a3.6 3.6 0 0 1-3.6-3.6Z' fill='url(%23b)'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M0 15.992C0 7.157 7.157 0 15.992 0a3.6 3.6 0 0 1 0 7.2A8.789 8.789 0 0 0 7.2 15.992c0 2.406.981 4.61 2.588 6.24a3.6 3.6 0 0 1-5.126 5.056C1.807 24.393 0 20.402 0 15.992Z' fill='url(%23c)'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M4.661 22.232a3.6 3.6 0 0 1 5.091-.035c1.63 1.606 3.834 2.587 6.24 2.587a3.6 3.6 0 0 1 0 7.2c-4.41 0-8.401-1.807-11.295-4.661a3.6 3.6 0 0 1-.036-5.091Z' fill='url(%23d)'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M28.384 12.392a3.6 3.6 0 0 1 3.6 3.6c0 8.835-7.157 15.992-15.992 15.992a3.6 3.6 0 0 1 0-7.2 8.789 8.789 0 0 0 8.792-8.792 3.6 3.6 0 0 1 3.6-3.6Z' fill='url(%23e)'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M28.385 12.392a3.6 3.6 0 0 1 3.6 3.6v12.392a3.6 3.6 0 0 1-7.2 0V15.992a3.6 3.6 0 0 1 3.6-3.6Z' fill='url(%23f)'/%3E%3Cg clip-path='url(%23g)'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M22.232 4.662a3.6 3.6 0 0 1 5.091.035c2.855 2.894 4.662 6.885 4.662 11.295a3.6 3.6 0 0 1-7.2 0c0-2.406-.982-4.61-2.588-6.24a3.6 3.6 0 0 1 .035-5.09Z' fill='url(%23h)'/%3E%3C/g%3E%3Cdefs%3E%3ClinearGradient id='a' x1='26.4' y1='9.6' x2='28.8' y2='15' gradientUnits='userSpaceOnUse'%3E%3Cstop stop-color='%237E22CE'/%3E%3Cstop offset='1' stop-color='%238B5CF6'/%3E%3C/linearGradient%3E%3ClinearGradient id='b' x1='26.8' y1='9.4' x2='17.8' y2='3.6' gradientUnits='userSpaceOnUse'%3E%3Cstop stop-color='%23EF4444'/%3E%3Cstop offset='1' stop-color='%23DC2626'/%3E%3C/linearGradient%3E%3ClinearGradient id='c' x1='3.6' y1='14' x2='5.4' y2='24.8' gradientUnits='userSpaceOnUse'%3E%3Cstop stop-color='%2322C55E'/%3E%3Cstop offset='1' stop-color='%2315803D'/%3E%3C/linearGradient%3E%3ClinearGradient id='d' x1='4.8' y1='22.2' x2='14.4' y2='29.2' gradientUnits='userSpaceOnUse'%3E%3Cstop stop-color='%2394A3B8'/%3E%3Cstop offset='.958' stop-color='%2364748B'/%3E%3Cstop offset='1' stop-color='%2364748B'/%3E%3C/linearGradient%3E%3ClinearGradient id='e' x1='28.4' y1='22.173' x2='22.188' y2='28.384' gradientUnits='userSpaceOnUse'%3E%3Cstop stop-color='%23D97706'/%3E%3Cstop offset='1' stop-color='%23FBBF24'/%3E%3C/linearGradient%3E%3ClinearGradient id='f' x1='29.2' y1='54.4' x2='30.626' y2='54.256' gradientUnits='userSpaceOnUse'%3E%3Cstop stop-color='%23FBBF24'/%3E%3Cstop offset='1' stop-color='%23FBBF24'/%3E%3C/linearGradient%3E%3ClinearGradient id='h' x1='26.4' y1='9.6' x2='28.8' y2='15' gradientUnits='userSpaceOnUse'%3E%3Cstop stop-color='%237E22CE'/%3E%3Cstop offset='1' stop-color='%238B5CF6'/%3E%3C/linearGradient%3E%3CclipPath id='g'%3E%3Cpath fill='%23fff' transform='translate(24.8 12)' d='M0 0h7.2v8H0z'/%3E%3C/clipPath%3E%3C/defs%3E%3C/svg%3E" />
18
18
  {{{ headTags }}}
19
+ <script>
20
+ window.allureReportOptions = {{{ reportOptions }}}
21
+ </script>
19
22
  </head>
20
23
  <body>
21
24
  <div id="app"></div>
@@ -38,9 +41,6 @@ const template = `<!DOCTYPE html>
38
41
  });
39
42
  </script>
40
43
  {{/if}}
41
- <script>
42
- window.allureReportOptions = {{{ reportOptions }}}
43
- </script>
44
44
  {{{ reportFilesScript }}}
45
45
  </body>
46
46
  </html>
@@ -73,10 +73,9 @@ const createBreadcrumbs = (convertedTr) => {
73
73
  return acc;
74
74
  }, []);
75
75
  };
76
- export const generateTestResults = async (writer, store, trs, filter) => {
77
- const allTr = trs.filter((tr) => (filter ? filter(tr) : true));
76
+ export const generateTestResults = async (writer, store, trs) => {
78
77
  let convertedTrs = [];
79
- for (const tr of allTr) {
78
+ for (const tr of trs) {
80
79
  const trFixtures = await store.fixturesByTrId(tr.id);
81
80
  const convertedTrFixtures = trFixtures.map(convertFixtureResult);
82
81
  const convertedTr = convertTestResult(tr);
@@ -135,7 +134,9 @@ export const generateTree = async (writer, treeFilename, labels, tests, options)
135
134
  await writer.writeWidget(treeFilename, tree);
136
135
  };
137
136
  const buildTreeByLabels = (tests, labels) => {
138
- return createTreeByLabels(tests, labels, leafFactory, undefined, (group, leaf) => incrementStatistic(group.statistic, leaf.status));
137
+ return createTreeByLabels(tests, labels, leafFactory, undefined, (group, leaf) => {
138
+ incrementStatistic(group.statistic, leaf.status);
139
+ });
139
140
  };
140
141
  const buildTreeByTitlePath = (tests) => {
141
142
  const testsWithTitlePath = [];
@@ -188,18 +189,25 @@ const buildTreeByTitlePath = (tests) => {
188
189
  };
189
190
  };
190
191
  const buildTreeByLabelsAndTitlePathCombined = (tests, labels) => createTreeByLabelsAndTitlePath(tests, labels, leafFactory, undefined, (group, leaf) => incrementStatistic(group.statistic, leaf.status));
191
- const leafFactory = ({ id, name, status, duration, flaky, start, retry, retriesCount, transition, tooltips, }) => ({
192
- nodeId: id,
193
- name,
194
- status,
195
- duration,
196
- flaky,
197
- start,
198
- retry,
199
- retriesCount,
200
- transition,
201
- tooltips,
202
- });
192
+ const leafFactory = ({ id, name, status, duration, flaky, start, retry, retriesCount, transition, tooltips, historyId, groupedLabels, }) => {
193
+ const leaf = {
194
+ nodeId: id,
195
+ id: historyId ?? id,
196
+ name,
197
+ status,
198
+ duration,
199
+ flaky,
200
+ start,
201
+ retry,
202
+ retriesCount,
203
+ transition,
204
+ tooltips,
205
+ };
206
+ if (groupedLabels.tag && groupedLabels.tag.length > 0) {
207
+ leaf.tags = groupedLabels.tag;
208
+ }
209
+ return leaf;
210
+ };
203
211
  export const generateEnvironmentJson = async (writer, env) => {
204
212
  await writer.writeWidget("allure_environment.json", env);
205
213
  };
@@ -274,7 +282,7 @@ export const generateGlobals = async (writer, payload) => {
274
282
  }
275
283
  await writer.writeWidget("globals.json", globals);
276
284
  };
277
- export const generateQualityGateResults = async (writer, qualityGateResults = []) => {
285
+ export const generateQualityGateResults = async (writer, qualityGateResults = {}) => {
278
286
  await writer.writeWidget("quality-gate.json", qualityGateResults);
279
287
  };
280
288
  export const generateStaticFiles = async (payload) => {
@@ -350,9 +358,25 @@ export const generateStaticFiles = async (payload) => {
350
358
  }
351
359
  };
352
360
  export const generateAllCharts = async (writer, store, options, context) => {
353
- const { charts = defaultChartsConfig } = options;
354
- const generatedChartsData = await generateCharts(charts, store, context.reportName, randomUUID);
361
+ const { charts = defaultChartsConfig, filter } = options;
362
+ const generatedChartsData = await generateCharts(charts, store, context.reportName, randomUUID, filter);
355
363
  if (Object.keys(generatedChartsData.general).length > 0) {
356
364
  await writer.writeWidget("charts.json", generatedChartsData);
357
365
  }
358
366
  };
367
+ export const generateTreeFilters = async (writer, testResults) => {
368
+ const trTags = new Set();
369
+ for (const tr of testResults) {
370
+ if (tr.labels.length === 0) {
371
+ continue;
372
+ }
373
+ Object.values(tr.groupedLabels.tag ?? []).forEach((tag) => {
374
+ trTags.add(tag);
375
+ });
376
+ }
377
+ if (trTags.size === 0) {
378
+ return Promise.resolve();
379
+ }
380
+ const tags = Array.from(trTags).sort((a, b) => a.localeCompare(b));
381
+ await writer.writeWidget("tree-filters.json", { tags });
382
+ };
package/dist/model.d.ts CHANGED
@@ -5,7 +5,7 @@ export type AwesomeOptions = {
5
5
  singleFile?: boolean;
6
6
  logo?: string;
7
7
  theme?: "light" | "dark" | "auto";
8
- reportLanguage?: "en";
8
+ reportLanguage?: string;
9
9
  groupBy?: string[];
10
10
  layout?: "base" | "split";
11
11
  environments?: Record<string, EnvironmentsConfig>;
package/dist/plugin.js CHANGED
@@ -16,7 +16,7 @@ import { preciseTreeLabels } from "@allurereport/plugin-api";
16
16
  import { join } from "node:path";
17
17
  import { filterEnv } from "./environments.js";
18
18
  import { generateTimeline } from "./generateTimeline.js";
19
- import { generateAllCharts, generateAttachmentsFiles, generateEnvironmentJson, generateEnvirontmentsList, generateGlobals, generateHistoryDataPoints, generateNav, generateQualityGateResults, generateStaticFiles, generateStatistic, generateTestCases, generateTestEnvGroups, generateTestResults, generateTree, generateVariables, } from "./generators.js";
19
+ import { generateAllCharts, generateAttachmentsFiles, generateEnvironmentJson, generateEnvirontmentsList, generateGlobals, generateHistoryDataPoints, generateNav, generateQualityGateResults, generateStaticFiles, generateStatistic, generateTestCases, generateTestEnvGroups, generateTestResults, generateTree, generateTreeFilters, generateVariables, } from "./generators.js";
20
20
  import { InMemoryReportDataWriter, ReportFileDataWriter } from "./writer.js";
21
21
  export class AwesomePlugin {
22
22
  constructor(options = {}) {
@@ -27,7 +27,7 @@ export class AwesomePlugin {
27
27
  const environmentItems = await store.metadataByKey("allure_environment");
28
28
  const reportEnvironments = await store.allEnvironments();
29
29
  const attachments = await store.allAttachments();
30
- const allTrs = await store.allTestResults({ includeHidden: true });
30
+ const allTrs = await store.allTestResults({ includeHidden: true, filter });
31
31
  const statistics = await store.testsStatistic(filter);
32
32
  const environments = await store.allEnvironments();
33
33
  const envStatistics = new Map();
@@ -35,7 +35,7 @@ export class AwesomePlugin {
35
35
  const globalAttachments = await store.allGlobalAttachments();
36
36
  const globalExitCode = await store.globalExitCode();
37
37
  const globalErrors = await store.allGlobalErrors();
38
- const qualityGateResults = await store.qualityGateResults();
38
+ const qualityGateResults = await store.qualityGateResultsByEnv();
39
39
  for (const env of environments) {
40
40
  envStatistics.set(env, await store.testsStatistic(filterEnv(env, filter)));
41
41
  }
@@ -45,9 +45,9 @@ export class AwesomePlugin {
45
45
  envs: environments,
46
46
  });
47
47
  await generateAllCharts(__classPrivateFieldGet(this, _AwesomePlugin_writer, "f"), store, this.options, context);
48
- await generateTimeline(__classPrivateFieldGet(this, _AwesomePlugin_writer, "f"), store, this.options);
49
- const convertedTrs = await generateTestResults(__classPrivateFieldGet(this, _AwesomePlugin_writer, "f"), store, allTrs, this.options.filter);
48
+ const convertedTrs = await generateTestResults(__classPrivateFieldGet(this, _AwesomePlugin_writer, "f"), store, allTrs);
50
49
  const hasGroupBy = groupBy.length > 0;
50
+ await generateTimeline(__classPrivateFieldGet(this, _AwesomePlugin_writer, "f"), convertedTrs, this.options);
51
51
  const treeLabels = hasGroupBy
52
52
  ? preciseTreeLabels(groupBy, convertedTrs, ({ labels }) => labels.map(({ name }) => name))
53
53
  : [];
@@ -63,6 +63,7 @@ export class AwesomePlugin {
63
63
  });
64
64
  await generateNav(__classPrivateFieldGet(this, _AwesomePlugin_writer, "f"), envConvertedTrs, join(reportEnvironment, "nav.json"));
65
65
  }
66
+ await generateTreeFilters(__classPrivateFieldGet(this, _AwesomePlugin_writer, "f"), convertedTrs);
66
67
  await generateEnvirontmentsList(__classPrivateFieldGet(this, _AwesomePlugin_writer, "f"), store);
67
68
  await generateVariables(__classPrivateFieldGet(this, _AwesomePlugin_writer, "f"), store);
68
69
  if (environmentItems?.length) {
@@ -113,8 +114,8 @@ export class AwesomePlugin {
113
114
  };
114
115
  }
115
116
  async info(context, store) {
116
- const allTrs = (await store.allTestResults()).filter((tr) => this.options.filter ? this.options.filter(tr) : true);
117
- const newTrs = await store.allNewTestResults();
117
+ const allTrs = await store.allTestResults({ filter: this.options.filter });
118
+ const newTrs = await store.allNewTestResults(this.options.filter);
118
119
  const retryTrs = allTrs.filter((tr) => !!tr?.retries?.length);
119
120
  const flakyTrs = allTrs.filter((tr) => !!tr?.flaky);
120
121
  const duration = allTrs.reduce((acc, { duration: trDuration = 0 }) => acc + trDuration, 0);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@allurereport/plugin-awesome",
3
- "version": "3.0.1",
3
+ "version": "3.2.0",
4
4
  "description": "Allure Awesome Plugin – brand new HTML report with modern design and new features",
5
5
  "keywords": [
6
6
  "allure",
@@ -30,18 +30,20 @@
30
30
  "test": "rimraf ./out && vitest run"
31
31
  },
32
32
  "dependencies": {
33
- "@allurereport/charts-api": "3.0.1",
34
- "@allurereport/core-api": "3.0.1",
35
- "@allurereport/plugin-api": "3.0.1",
36
- "@allurereport/web-awesome": "3.0.1",
37
- "@allurereport/web-commons": "3.0.1",
33
+ "@allurereport/charts-api": "3.2.0",
34
+ "@allurereport/core-api": "3.2.0",
35
+ "@allurereport/plugin-api": "3.2.0",
36
+ "@allurereport/web-awesome": "3.2.0",
37
+ "@allurereport/web-commons": "3.2.0",
38
38
  "d3-shape": "^3.2.0",
39
- "handlebars": "^4.7.8"
39
+ "handlebars": "^4.7.8",
40
+ "markdown-it": "^14.1.0"
40
41
  },
41
42
  "devDependencies": {
42
43
  "@stylistic/eslint-plugin": "^2.6.1",
43
44
  "@types/d3-shape": "^3.1.6",
44
45
  "@types/eslint": "^8.56.11",
46
+ "@types/markdown-it": "^14.1.2",
45
47
  "@types/node": "^20.17.9",
46
48
  "@typescript-eslint/eslint-plugin": "^8.0.0",
47
49
  "@typescript-eslint/parser": "^8.0.0",