@allurereport/plugin-awesome 3.16.0 → 3.17.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,9 +1,9 @@
1
1
  import type { CategoryDefinition } from "@allurereport/core-api";
2
- import type { AwesomeTestResult } from "@allurereport/web-awesome";
2
+ import { type ReportTestResult } from "@allurereport/plugin-api";
3
3
  import type { AwesomeDataWriter } from "./writer.js";
4
- export declare const applyCategoriesToTestResults: (tests: AwesomeTestResult[], categories: CategoryDefinition[]) => void;
4
+ export declare const applyCategoriesToTestResults: (tests: ReportTestResult[], categories: CategoryDefinition[]) => void;
5
5
  export declare const generateCategories: (writer: AwesomeDataWriter, { tests, categories, filename, environmentCount, selectedEnvironmentCount, environments, defaultEnvironment, }: {
6
- tests: AwesomeTestResult[];
6
+ tests: ReportTestResult[];
7
7
  categories: CategoryDefinition[];
8
8
  filename?: string;
9
9
  environmentCount?: number;
@@ -1,7 +1,7 @@
1
1
  import { type TestFixtureResult, type TestResult, type TestStepResult } from "@allurereport/core-api";
2
- import type { AwesomeFixtureResult, AwesomeTestResult, AwesomeTestStepResult } from "@allurereport/web-awesome";
2
+ import type { ReportFixtureResult, ReportTestResult, ReportTestStepResult } from "@allurereport/plugin-api";
3
3
  export declare const convertTestResult: (tr: TestResult, options?: {
4
4
  hideLabels?: readonly (string | RegExp)[];
5
- }) => AwesomeTestResult;
6
- export declare const convertTestStepResult: (tsr: TestStepResult) => AwesomeTestStepResult;
7
- export declare const convertFixtureResult: (fr: TestFixtureResult) => AwesomeFixtureResult;
5
+ }) => ReportTestResult;
6
+ export declare const convertTestStepResult: (tsr: TestStepResult) => ReportTestStepResult;
7
+ export declare const convertFixtureResult: (fr: TestFixtureResult) => ReportFixtureResult;
@@ -24,7 +24,8 @@ export const convertTestResult = (tr, options = {}) => {
24
24
  historyId: tr.historyId,
25
25
  flaky: tr.flaky,
26
26
  muted: tr.muted,
27
- known: tr.known,
27
+ resolution: tr.resolution,
28
+ resolutionComment: tr.resolutionComment,
28
29
  isRetry: tr.isRetry,
29
30
  labels,
30
31
  groupedLabels: mapLabelsByName(labels),
@@ -33,6 +34,7 @@ export const convertTestResult = (tr, options = {}) => {
33
34
  steps: (tr.steps ?? []).map(convertTestStepResult),
34
35
  error: tr.error,
35
36
  testCase: tr.testCase,
37
+ retryHash: tr.retryHash,
36
38
  descriptionHtml: tr.descriptionHtml ?? markdownToHtml(tr.description),
37
39
  environment: tr.environment,
38
40
  setup: [],
@@ -1,26 +1,28 @@
1
- import { type AttachmentLink, type EnvironmentIdentity, type EnvironmentItem, type Statistic, type TestEnvGroup, type TestResult } from "@allurereport/core-api";
2
- import type { AllureStore, GlobalAttachmentLink, ExitCode, PluginContext, PluginGlobalError, QualityGateValidationResult, ReportFiles, ResultFile } from "@allurereport/plugin-api";
3
- import type { AwesomeExecutorInfo, AwesomeRunSummary, AwesomeTestResult } from "@allurereport/web-awesome";
1
+ import { type AttachmentLink, type EnvironmentIdentity, type EnvironmentItem, type MetricSample, type Statistic, type TestEnvGroup, type TestResult } from "@allurereport/core-api";
2
+ import type { AllureStore, ReportExecutorInfo, ReportRunSummary, ReportTestResult, GlobalAttachmentLink, ExitCode, PluginContext, PluginGlobalError, QualityGateValidationResult, ReportFiles, ResultFile } from "@allurereport/plugin-api";
4
3
  import type { AwesomeOptions, TemplateManifest } from "./model.js";
5
4
  import type { AwesomeDataWriter, ReportFile } from "./writer.js";
6
- export declare const readTemplateManifest: (singleFileMode?: boolean) => Promise<TemplateManifest>;
5
+ export declare const readTemplateManifest: (_singleFileMode?: boolean) => Promise<TemplateManifest>;
7
6
  export declare const generateTestResults: (_writer: AwesomeDataWriter, store: AllureStore, trs: TestResult[], options?: {
8
7
  hideLabels?: readonly (string | RegExp)[];
9
- }) => Promise<AwesomeTestResult[]>;
10
- export declare const generateTestCases: (writer: AwesomeDataWriter, trs: AwesomeTestResult[]) => Promise<void>;
8
+ }) => Promise<ReportTestResult[]>;
9
+ export declare const generateTestCases: (writer: AwesomeDataWriter, trs: ReportTestResult[]) => Promise<void>;
11
10
  export declare const generateTestEnvGroups: (writer: AwesomeDataWriter, groups: TestEnvGroup[]) => Promise<void>;
12
- export declare const generateNav: (writer: AwesomeDataWriter, trs: AwesomeTestResult[], filename?: string) => Promise<void>;
13
- export declare const generateSearchIndex: (writer: AwesomeDataWriter, trs: AwesomeTestResult[], filename?: string) => Promise<void>;
14
- export declare const getRunSummary: (testResults: Pick<TestResult, "start" | "stop">[]) => AwesomeRunSummary | undefined;
15
- export declare const generateTree: (writer: AwesomeDataWriter, treeFilename: string, labels: string[], tests: AwesomeTestResult[], options?: {
11
+ export declare const generateNav: (writer: AwesomeDataWriter, trs: ReportTestResult[], filename?: string) => Promise<void>;
12
+ export declare const generateSearchIndex: (writer: AwesomeDataWriter, trs: ReportTestResult[], filename?: string) => Promise<void>;
13
+ export declare const getRunSummary: (testResults: Pick<TestResult, "start" | "stop">[]) => ReportRunSummary | undefined;
14
+ export declare const generateTree: (writer: AwesomeDataWriter, treeFilename: string, labels: string[], tests: ReportTestResult[], options?: {
16
15
  appendTitlePath?: boolean;
17
16
  }) => Promise<void>;
17
+ export declare const generateResolutionCategories: (writer: AwesomeDataWriter, tests: ReportTestResult[], filename?: string) => Promise<void>;
18
18
  export declare const generateEnvironmentJson: (writer: AwesomeDataWriter, env: EnvironmentItem[]) => Promise<void>;
19
19
  export declare const generateEnvirontmentsList: (writer: AwesomeDataWriter, store: AllureStore) => Promise<void>;
20
20
  export declare const generateVariables: (writer: AwesomeDataWriter, store: AllureStore) => Promise<void>;
21
21
  export declare const generateStatistic: (writer: AwesomeDataWriter, data: {
22
22
  stats: Statistic;
23
23
  statsByEnv: Map<string, Statistic>;
24
+ pieStats?: Statistic;
25
+ pieStatsByEnv?: Map<string, Statistic>;
24
26
  envs: EnvironmentIdentity[];
25
27
  }) => Promise<void>;
26
28
  export declare const generateAttachmentsFiles: (writer: AwesomeDataWriter, attachmentLinks: AttachmentLink[], contentFunction: (id: string) => Promise<ResultFile | undefined>) => Promise<Map<string, string>>;
@@ -34,7 +36,7 @@ export declare const generateGlobals: (writer: AwesomeDataWriter, payload: {
34
36
  contentFunction: (id: string) => Promise<ResultFile | undefined>;
35
37
  }) => Promise<void>;
36
38
  export declare const generateQualityGateResults: (writer: AwesomeDataWriter, qualityGateResults?: Record<string, QualityGateValidationResult[]>, options?: {
37
- tests?: AwesomeTestResult[];
39
+ tests?: ReportTestResult[];
38
40
  labels?: string[];
39
41
  appendTitlePath?: boolean;
40
42
  }) => Promise<void>;
@@ -45,8 +47,19 @@ export declare const generateStaticFiles: (payload: AwesomeOptions & {
45
47
  reportDataFiles: ReportFile[];
46
48
  reportUuid: string;
47
49
  reportName: string;
48
- executor?: AwesomeExecutorInfo;
49
- runSummary?: AwesomeRunSummary;
50
+ executor?: ReportExecutorInfo;
51
+ runSummary?: ReportRunSummary;
50
52
  }) => Promise<void>;
51
53
  export declare const generateAllCharts: (writer: AwesomeDataWriter, store: AllureStore, options: AwesomeOptions, context: PluginContext) => Promise<void>;
52
- export declare const generateTreeFilters: (writer: AwesomeDataWriter, testResults: AwesomeTestResult[]) => Promise<void>;
54
+ export type AwesomeMetricsWidget = {
55
+ current: MetricSample[];
56
+ history: {
57
+ uuid: string;
58
+ name: string;
59
+ timestamp: number;
60
+ url?: string;
61
+ metrics: Record<string, number>;
62
+ }[];
63
+ };
64
+ export declare const generateMetricsWidget: (writer: AwesomeDataWriter, store: AllureStore, reportUuid: string) => Promise<boolean>;
65
+ export declare const generateTreeFilters: (writer: AwesomeDataWriter, testResults: ReportTestResult[]) => Promise<void>;
@@ -1,14 +1,12 @@
1
1
  import { randomUUID } from "node:crypto";
2
- import { readFile, readdir } from "node:fs/promises";
3
- import { createRequire } from "node:module";
4
- import { basename, dirname, join } from "node:path";
5
2
  import { defaultChartsConfig } from "@allurereport/charts-api";
6
3
  import { appLoaderFaviconDataUri, appLoaderStyles, compareBy, createAppLoaderMarkup, createBaseUrlScript, createFaviconLinkTag, createFontLinkTag, createReportDataScript, stringifyForInlineScript, createScriptTag, createStylesLinkTag, incrementStatistic, joinPosixPath, nullsLast, ordinal, } from "@allurereport/core-api";
7
4
  import { collapseTreeGroups, createTreeByLabels, createTreeByLabelsAndTitlePath, createTreeByTitlePath, preciseTreeLabels, processTree, } from "@allurereport/plugin-api";
5
+ import { copyReportStaticAssets, getReportStaticAsset, readReportStaticAssets, } from "@allurereport/plugin-api/static-assets";
8
6
  import { generateCharts, getPieChartValues } from "@allurereport/web-commons";
9
7
  import Handlebars from "handlebars";
10
8
  import { convertFixtureResult, convertTestResult } from "./converters.js";
11
- const require = createRequire(import.meta.url);
9
+ const reportStaticArchive = new URL("../dist/static/report.tar", import.meta.url);
12
10
  const template = `<!DOCTYPE html>
13
11
  <html dir="ltr" lang="en">
14
12
  <head>
@@ -48,10 +46,9 @@ const template = `<!DOCTYPE html>
48
46
  </html>
49
47
  `;
50
48
  const compiledTemplate = Handlebars.compile(template);
51
- export const readTemplateManifest = async (singleFileMode) => {
52
- const templateManifestSource = require.resolve(`@allurereport/web-awesome/dist/${singleFileMode ? "single" : "multi"}/manifest.json`);
53
- const templateManifest = await readFile(templateManifestSource, { encoding: "utf-8" });
54
- return JSON.parse(templateManifest);
49
+ export const readTemplateManifest = async (_singleFileMode) => {
50
+ const { manifest } = await readReportStaticAssets(reportStaticArchive);
51
+ return manifest;
55
52
  };
56
53
  const createBreadcrumbs = (convertedTr) => {
57
54
  const labelsByType = convertedTr.labels.reduce((acc, label) => {
@@ -92,6 +89,7 @@ export const generateTestResults = async (_writer, store, trs, options = {}) =>
92
89
  const convertedTr = convertTestResult(tr, {
93
90
  hideLabels: options.hideLabels,
94
91
  });
92
+ const resolutionIssue = await store.resolutionIssueByTestResultId(tr.id);
95
93
  convertedTr.history = related.historyByTrId.get(tr.id) ?? [];
96
94
  convertedTr.retries = related.retriesByTrId.get(tr.id) ?? [];
97
95
  convertedTr.retriesCount = convertedTr.retries.length;
@@ -104,6 +102,7 @@ export const generateTestResults = async (_writer, store, trs, options = {}) =>
104
102
  type: "attachment",
105
103
  }));
106
104
  convertedTr.breadcrumbs = createBreadcrumbs(convertedTr);
105
+ convertedTr.resolutionIssue = resolutionIssue;
107
106
  convertedTrs.push(convertedTr);
108
107
  }
109
108
  convertedTrs = convertedTrs.sort(nullsLast(compareBy("start", ordinal()))).map((tr, idx) => ({
@@ -268,7 +267,7 @@ const buildTreeByTitlePath = (tests) => {
268
267
  };
269
268
  };
270
269
  const buildTreeByLabelsAndTitlePathCombined = (tests, labels) => collapseTreeGroups(createTreeByLabelsAndTitlePath(tests, labels, leafFactory, undefined, (group, leaf) => incrementStatistic(group.statistic, leaf.status)));
271
- const leafFactory = ({ id, name, status, duration, flaky, start, retry, retriesCount, transition, tooltips, historyId, groupedLabels, categories, }) => {
270
+ const leafFactory = ({ id, name, status, duration, flaky, start, retry, retriesCount, resolution, transition, tooltips, historyId, groupedLabels, categories, }) => {
272
271
  const leaf = {
273
272
  nodeId: id,
274
273
  id: historyId ?? id,
@@ -279,6 +278,7 @@ const leafFactory = ({ id, name, status, duration, flaky, start, retry, retriesC
279
278
  start,
280
279
  retry,
281
280
  retriesCount,
281
+ resolution,
282
282
  transition,
283
283
  tooltips,
284
284
  };
@@ -290,6 +290,53 @@ const leafFactory = ({ id, name, status, duration, flaky, start, retry, retriesC
290
290
  }
291
291
  return leaf;
292
292
  };
293
+ const resolutionOrder = ["issue", "muted", "accepted"];
294
+ const getResolutionGroupName = (test) => {
295
+ if (test.resolution === "issue") {
296
+ return test.resolutionIssue?.id ?? test.resolution;
297
+ }
298
+ return test.resolutionComment ?? test.resolution ?? "";
299
+ };
300
+ const resolutionTestResultFactory = (test, index) => ({
301
+ nodeId: test.id,
302
+ id: test.historyId ?? test.id,
303
+ name: test.name,
304
+ status: test.status,
305
+ duration: test.duration,
306
+ flaky: test.flaky,
307
+ transition: test.transition,
308
+ retry: test.retry,
309
+ retriesCount: test.retriesCount,
310
+ resolution: test.resolution,
311
+ groupOrder: index + 1,
312
+ tooltips: test.tooltips,
313
+ });
314
+ export const generateResolutionCategories = async (writer, tests, filename = "resolution-categories.json") => {
315
+ const groupsById = new Map();
316
+ tests
317
+ .filter((test) => !test.isRetry && test.resolution)
318
+ .forEach((test) => {
319
+ const resolution = test.resolution;
320
+ const groupId = resolution === "issue"
321
+ ? `${resolution}:${test.resolutionIssue?.id ?? test.id}`
322
+ : `${resolution}:${test.resolutionComment ?? test.id}`;
323
+ const group = groupsById.get(groupId) ?? {
324
+ id: groupId,
325
+ resolution,
326
+ name: getResolutionGroupName(test),
327
+ comment: test.resolutionComment ?? test.resolutionIssue?.comment,
328
+ issue: test.resolutionIssue,
329
+ testResults: [],
330
+ };
331
+ group.testResults.push(resolutionTestResultFactory(test, group.testResults.length));
332
+ groupsById.set(groupId, group);
333
+ });
334
+ const groups = [...groupsById.values()].sort((a, b) => {
335
+ const resolutionDiff = resolutionOrder.indexOf(a.resolution) - resolutionOrder.indexOf(b.resolution);
336
+ return resolutionDiff || a.name.localeCompare(b.name);
337
+ });
338
+ await writer.writeWidget(filename, { groups });
339
+ };
293
340
  export const generateEnvironmentJson = async (writer, env) => {
294
341
  await writer.writeWidget("allure_environment.json", env);
295
342
  };
@@ -307,16 +354,16 @@ export const generateVariables = async (writer, store) => {
307
354
  }
308
355
  };
309
356
  export const generateStatistic = async (writer, data) => {
310
- const { stats, statsByEnv, envs } = data;
357
+ const { stats, statsByEnv, pieStats = stats, pieStatsByEnv, envs } = data;
311
358
  await writer.writeWidget("statistic.json", stats);
312
- await writer.writeWidget("pie_chart.json", getPieChartValues(stats));
359
+ await writer.writeWidget("pie_chart.json", getPieChartValues(pieStats));
313
360
  for (const env of envs) {
314
361
  const envStats = statsByEnv.get(env.id);
315
362
  if (!envStats) {
316
363
  continue;
317
364
  }
318
365
  await writer.writeWidget(joinPosixPath(env.id, "statistic.json"), envStats);
319
- await writer.writeWidget(joinPosixPath(env.id, "pie_chart.json"), envStats);
366
+ await writer.writeWidget(joinPosixPath(env.id, "pie_chart.json"), getPieChartValues(pieStatsByEnv?.get(env.id) ?? envStats));
320
367
  }
321
368
  };
322
369
  export const generateAttachmentsFiles = async (writer, attachmentLinks, contentFunction) => {
@@ -400,14 +447,13 @@ export const generateQualityGateResults = async (writer, qualityGateResults = {}
400
447
  await writer.writeWidget("quality-gate.json", resultsWithTrees);
401
448
  };
402
449
  export const generateStaticFiles = async (payload) => {
403
- const { id, reportName = "Allure Report", reportLanguage = "en", singleFile, logo = "", theme = "auto", groupBy, reportFiles, reportDataFiles, reportUuid, allureVersion, layout = "base", defaultSection = "", ci, executor, runSummary, stepTreeExpansion, defaultSortBy, } = payload;
404
- const manifest = await readTemplateManifest(payload.singleFile);
450
+ const { id, reportName = "Allure Report", reportLanguage = "en", logo = "", theme = "auto", groupBy, reportFiles, reportDataFiles, reportUuid, allureVersion, layout = "base", defaultSection = "", ci, executor, runSummary, stepTreeExpansion, defaultSortBy, } = payload;
451
+ const staticAssets = await readReportStaticAssets(reportStaticArchive);
452
+ const { manifest } = staticAssets;
405
453
  const headTags = [];
406
454
  const bodyTags = [];
407
- const sections = ["charts", "timeline"];
455
+ const sections = payload.sections?.length ? payload.sections : ["charts", "timeline"];
408
456
  if (!payload.singleFile) {
409
- const manifestPath = require.resolve(join("@allurereport/web-awesome/dist", singleFile ? "single" : "multi", "manifest.json"));
410
- const templateDir = dirname(manifestPath);
411
457
  for (const key in manifest) {
412
458
  const fileName = manifest[key];
413
459
  if (key.includes(".woff")) {
@@ -420,19 +466,16 @@ export const generateStaticFiles = async (payload) => {
420
466
  bodyTags.push(createScriptTag(fileName));
421
467
  }
422
468
  }
423
- for (const fileName of await readdir(templateDir)) {
424
- if (fileName === "manifest.json") {
425
- continue;
426
- }
427
- const filePath = join(templateDir, fileName);
428
- const fileContent = await readFile(filePath);
429
- await reportFiles.addFile(basename(filePath), fileContent);
430
- }
469
+ await copyReportStaticAssets(staticAssets, reportFiles);
431
470
  }
432
471
  else {
433
472
  const mainJs = manifest["main.js"];
434
- const mainJsSource = require.resolve(`@allurereport/web-awesome/dist/single/${mainJs}`);
435
- const mainJsContent = await readFile(mainJsSource);
473
+ const mainCss = manifest["main.css"];
474
+ if (mainCss) {
475
+ const mainCssContent = getReportStaticAsset(staticAssets, mainCss);
476
+ headTags.push(createStylesLinkTag(`data:text/css;base64,${mainCssContent.toString("base64")}`));
477
+ }
478
+ const mainJsContent = getReportStaticAsset(staticAssets, mainJs);
436
479
  bodyTags.push(createScriptTag(`data:text/javascript;base64,${mainJsContent.toString("base64")}`));
437
480
  }
438
481
  const now = Date.now();
@@ -485,6 +528,26 @@ export const generateAllCharts = async (writer, store, options, context) => {
485
528
  await writer.writeWidget("charts.json", generatedChartsData);
486
529
  }
487
530
  };
531
+ export const generateMetricsWidget = async (writer, store, reportUuid) => {
532
+ const current = await store.allMetrics();
533
+ if (current.length === 0) {
534
+ return false;
535
+ }
536
+ const history = (await store.allHistoryDataPoints())
537
+ .filter(({ uuid, metrics = {} }) => uuid !== reportUuid && Object.keys(metrics).length > 0)
538
+ .map(({ uuid, name, timestamp, url, metrics = {} }) => ({
539
+ uuid,
540
+ name,
541
+ timestamp,
542
+ ...(url ? { url } : {}),
543
+ metrics,
544
+ }));
545
+ await writer.writeWidget("metrics.json", {
546
+ current,
547
+ history,
548
+ });
549
+ return true;
550
+ };
488
551
  export const generateTreeFilters = async (writer, testResults) => {
489
552
  const trTags = new Set();
490
553
  const trCategories = new Set();
package/dist/model.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { ChartOptions } from "@allurereport/charts-api";
2
2
  import type { CiDescriptor, EnvironmentsConfig, TestResult } from "@allurereport/core-api";
3
- import type { StepTreeExpansion } from "@allurereport/web-awesome";
3
+ import type { StepTreeExpansion } from "@allurereport/plugin-api";
4
4
  export type AwesomeOptions = {
5
5
  reportName?: string;
6
6
  singleFile?: boolean;
package/dist/plugin.js CHANGED
@@ -9,17 +9,31 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
9
9
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
10
10
  return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
11
11
  };
12
- var _AwesomePlugin_writer, _AwesomePlugin_generate;
13
- import { incrementStatistic, joinPosixPath } from "@allurereport/core-api";
12
+ var _AwesomePlugin_writer, _AwesomePlugin_generateAfterStart, _AwesomePlugin_generate;
13
+ import { incrementStatistic, joinPosixPath, } from "@allurereport/core-api";
14
14
  import { createPluginSummary, } from "@allurereport/plugin-api";
15
15
  import { preciseTreeLabels } from "@allurereport/plugin-api";
16
16
  import { applyCategoriesToTestResults, generateCategories } from "./categories.js";
17
17
  import { generateTimeline } from "./generateTimeline.js";
18
- import { generateAllCharts, generateAttachmentsFiles, generateEnvironmentJson, generateEnvirontmentsList, generateGlobals, generateHistoryDataPoints, generateNav, generateQualityGateResults, generateSearchIndex, generateStaticFiles, generateStatistic, generateTestCases, generateTestEnvGroups, generateTestResults, generateTree, generateTreeFilters, generateVariables, getRunSummary, } from "./generators.js";
18
+ import { generateAllCharts, generateAttachmentsFiles, generateEnvironmentJson, generateEnvirontmentsList, generateGlobals, generateHistoryDataPoints, generateMetricsWidget, generateNav, generateQualityGateResults, generateResolutionCategories, generateSearchIndex, generateStaticFiles, generateStatistic, generateTestCases, generateTestEnvGroups, generateTestResults, generateTree, generateTreeFilters, generateVariables, getRunSummary, } from "./generators.js";
19
19
  import { InMemoryReportDataWriter, ReportFileDataWriter } from "./writer.js";
20
20
  const statisticByTestResults = async (store, testResults) => {
21
21
  const statistic = { total: 0 };
22
22
  const related = await store.relatedByTestResultIds(testResults.map(({ id }) => id));
23
+ const incrementResolution = (testResult) => {
24
+ if (testResult.resolution === "issue") {
25
+ statistic.resolutions ?? (statistic.resolutions = {});
26
+ statistic.resolutions.issues = (statistic.resolutions.issues ?? 0) + 1;
27
+ }
28
+ if (testResult.resolution === "muted") {
29
+ statistic.resolutions ?? (statistic.resolutions = {});
30
+ statistic.resolutions.muted = (statistic.resolutions.muted ?? 0) + 1;
31
+ }
32
+ if (testResult.resolution === "accepted") {
33
+ statistic.resolutions ?? (statistic.resolutions = {});
34
+ statistic.resolutions.accepted = (statistic.resolutions.accepted ?? 0) + 1;
35
+ }
36
+ };
23
37
  for (const testResult of testResults) {
24
38
  if (testResult.isRetry) {
25
39
  continue;
@@ -34,13 +48,21 @@ const statisticByTestResults = async (store, testResults) => {
34
48
  if (testResult.transition === "new") {
35
49
  statistic.new = (statistic.new ?? 0) + 1;
36
50
  }
51
+ incrementResolution(testResult);
37
52
  }
38
53
  return statistic;
39
54
  };
55
+ const isActiveStatisticTestResult = (testResult) => testResult.resolution !== "muted" && testResult.resolution !== "accepted";
40
56
  export class AwesomePlugin {
41
57
  constructor(options = {}) {
42
58
  this.options = options;
43
59
  _AwesomePlugin_writer.set(this, void 0);
60
+ _AwesomePlugin_generateAfterStart.set(this, async (context, store) => {
61
+ if (!__classPrivateFieldGet(this, _AwesomePlugin_writer, "f")) {
62
+ throw new Error("call start first");
63
+ }
64
+ await __classPrivateFieldGet(this, _AwesomePlugin_generate, "f").call(this, context, store);
65
+ });
44
66
  _AwesomePlugin_generate.set(this, async (context, store) => {
45
67
  const { singleFile, groupBy = [], filter, appendTitlePath } = this.options ?? {};
46
68
  const hideLabels = context.hideLabels;
@@ -53,6 +75,8 @@ export class AwesomePlugin {
53
75
  const statistics = await store.testsStatistic(filter);
54
76
  const environments = await store.allEnvironmentIdentities();
55
77
  const envStatistics = new Map();
78
+ const pieStatistics = await statisticByTestResults(store, allTrs.filter(isActiveStatisticTestResult));
79
+ const pieEnvStatistics = new Map();
56
80
  const allTestEnvGroups = await store.allTestEnvGroups();
57
81
  const globalAttachments = await store.allGlobalAttachments();
58
82
  const globalAttachmentsByEnv = await store.allGlobalAttachmentsByEnv();
@@ -83,14 +107,19 @@ export class AwesomePlugin {
83
107
  }
84
108
  }
85
109
  await Promise.all(environments.map(async ({ id }) => {
86
- envStatistics.set(id, await statisticByTestResults(store, trsByEnvId.get(id) ?? []));
110
+ const envTrs = trsByEnvId.get(id) ?? [];
111
+ envStatistics.set(id, await statisticByTestResults(store, envTrs));
112
+ pieEnvStatistics.set(id, await statisticByTestResults(store, envTrs.filter(isActiveStatisticTestResult)));
87
113
  }));
88
114
  await generateStatistic(__classPrivateFieldGet(this, _AwesomePlugin_writer, "f"), {
89
115
  stats: statistics,
90
116
  statsByEnv: envStatistics,
117
+ pieStats: pieStatistics,
118
+ pieStatsByEnv: pieEnvStatistics,
91
119
  envs: environments,
92
120
  });
93
121
  await generateAllCharts(__classPrivateFieldGet(this, _AwesomePlugin_writer, "f"), store, this.options, context);
122
+ const hasMetrics = await generateMetricsWidget(__classPrivateFieldGet(this, _AwesomePlugin_writer, "f"), store, context.reportUuid);
94
123
  const convertedTrs = await generateTestResults(__classPrivateFieldGet(this, _AwesomePlugin_writer, "f"), store, allTrs, { hideLabels });
95
124
  applyCategoriesToTestResults(convertedTrs, categories);
96
125
  await generateCategories(__classPrivateFieldGet(this, _AwesomePlugin_writer, "f"), {
@@ -101,6 +130,7 @@ export class AwesomePlugin {
101
130
  defaultEnvironment: "default",
102
131
  selectedEnvironmentCount: environments.length,
103
132
  });
133
+ await generateResolutionCategories(__classPrivateFieldGet(this, _AwesomePlugin_writer, "f"), convertedTrs);
104
134
  const hasGroupBy = groupBy.length > 0;
105
135
  await generateTimeline(__classPrivateFieldGet(this, _AwesomePlugin_writer, "f"), allTrs, this.options, envIdByTrId);
106
136
  const treeLabels = hasGroupBy
@@ -131,6 +161,7 @@ export class AwesomePlugin {
131
161
  selectedEnvironmentCount: 1,
132
162
  filename: joinPosixPath(reportEnvironment.id, "categories.json"),
133
163
  });
164
+ await generateResolutionCategories(__classPrivateFieldGet(this, _AwesomePlugin_writer, "f"), envConvertedTrs, joinPosixPath(reportEnvironment.id, "resolution-categories.json"));
134
165
  }
135
166
  await generateTreeFilters(__classPrivateFieldGet(this, _AwesomePlugin_writer, "f"), convertedTrs);
136
167
  await generateEnvirontmentsList(__classPrivateFieldGet(this, _AwesomePlugin_writer, "f"), store);
@@ -153,8 +184,13 @@ export class AwesomePlugin {
153
184
  contentFunction: (id) => store.attachmentContentById(id),
154
185
  });
155
186
  const reportDataFiles = singleFile ? __classPrivateFieldGet(this, _AwesomePlugin_writer, "f").reportFiles() : [];
187
+ const configuredSections = this.options.sections ?? ["charts", "timeline"];
188
+ const sections = hasMetrics
189
+ ? [...new Set([...configuredSections, "metrics"])]
190
+ : configuredSections.filter((section) => section !== "metrics");
156
191
  await generateStaticFiles({
157
192
  ...this.options,
193
+ sections,
158
194
  id: context.id,
159
195
  allureVersion: context.allureVersion,
160
196
  reportFiles: context.reportFiles,
@@ -176,16 +212,10 @@ export class AwesomePlugin {
176
212
  await Promise.resolve();
177
213
  };
178
214
  this.update = async (context, store) => {
179
- if (!__classPrivateFieldGet(this, _AwesomePlugin_writer, "f")) {
180
- throw new Error("call start first");
181
- }
182
- await __classPrivateFieldGet(this, _AwesomePlugin_generate, "f").call(this, context, store);
215
+ await __classPrivateFieldGet(this, _AwesomePlugin_generateAfterStart, "f").call(this, context, store);
183
216
  };
184
217
  this.done = async (context, store) => {
185
- if (!__classPrivateFieldGet(this, _AwesomePlugin_writer, "f")) {
186
- throw new Error("call start first");
187
- }
188
- await __classPrivateFieldGet(this, _AwesomePlugin_generate, "f").call(this, context, store);
218
+ await __classPrivateFieldGet(this, _AwesomePlugin_generateAfterStart, "f").call(this, context, store);
189
219
  };
190
220
  }
191
221
  async info(context, store) {
@@ -204,4 +234,4 @@ export class AwesomePlugin {
204
234
  });
205
235
  }
206
236
  }
207
- _AwesomePlugin_writer = new WeakMap(), _AwesomePlugin_generate = new WeakMap();
237
+ _AwesomePlugin_writer = new WeakMap(), _AwesomePlugin_generateAfterStart = new WeakMap(), _AwesomePlugin_generate = new WeakMap();
Binary file
package/dist/writer.d.ts CHANGED
@@ -1,5 +1,4 @@
1
- import type { ReportFiles, ResultFile } from "@allurereport/plugin-api";
2
- import type { AwesomeTestResult } from "@allurereport/web-awesome";
1
+ import type { ReportTestResult, ReportFiles, ResultFile } from "@allurereport/plugin-api";
3
2
  export interface ReportFile {
4
3
  name: string;
5
4
  value: string;
@@ -7,7 +6,7 @@ export interface ReportFile {
7
6
  export interface AwesomeDataWriter {
8
7
  writeData(fileName: string, data: any): Promise<void>;
9
8
  writeWidget(fileName: string, data: any): Promise<void>;
10
- writeTestCase(test: AwesomeTestResult): Promise<void>;
9
+ writeTestCase(test: ReportTestResult): Promise<void>;
11
10
  writeAttachment(source: string, file: ResultFile): Promise<void>;
12
11
  }
13
12
  export declare class FileSystemReportDataWriter implements AwesomeDataWriter {
@@ -16,14 +15,14 @@ export declare class FileSystemReportDataWriter implements AwesomeDataWriter {
16
15
  constructor(output: string);
17
16
  writeData(fileName: string, data: any): Promise<void>;
18
17
  writeWidget(fileName: string, data: any): Promise<void>;
19
- writeTestCase(test: AwesomeTestResult): Promise<void>;
18
+ writeTestCase(test: ReportTestResult): Promise<void>;
20
19
  writeAttachment(source: string, file: ResultFile): Promise<void>;
21
20
  }
22
21
  export declare class InMemoryReportDataWriter implements AwesomeDataWriter {
23
22
  #private;
24
23
  writeData(fileName: string, data: any): Promise<void>;
25
24
  writeWidget(fileName: string, data: any): Promise<void>;
26
- writeTestCase(test: AwesomeTestResult): Promise<void>;
25
+ writeTestCase(test: ReportTestResult): Promise<void>;
27
26
  writeAttachment(fileName: string, file: ResultFile): Promise<void>;
28
27
  reportFiles(): ReportFile[];
29
28
  }
@@ -33,5 +32,5 @@ export declare class ReportFileDataWriter implements AwesomeDataWriter {
33
32
  writeData(fileName: string, data: any): Promise<void>;
34
33
  writeWidget(fileName: string, data: any): Promise<void>;
35
34
  writeAttachment(source: string, file: ResultFile): Promise<void>;
36
- writeTestCase(test: AwesomeTestResult): Promise<void>;
35
+ writeTestCase(test: ReportTestResult): Promise<void>;
37
36
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@allurereport/plugin-awesome",
3
- "version": "3.16.0",
3
+ "version": "3.17.0",
4
4
  "description": "Allure Awesome Plugin – brand new HTML report with modern design and new features",
5
5
  "keywords": [
6
6
  "allure",
@@ -23,23 +23,23 @@
23
23
  ".": "./dist/index.js"
24
24
  },
25
25
  "scripts": {
26
- "build": "run clean && tsc --project ./tsconfig.json",
26
+ "build": "run clean && tsc --project ./tsconfig.json && node ../../scripts/pack-report-static.mjs ../web-awesome/dist/multi ./dist/static/report.tar",
27
27
  "clean": "rimraf ./dist",
28
28
  "test": "rimraf ./out && vitest run",
29
29
  "lint": "oxlint --import-plugin src test features stories",
30
30
  "lint:fix": "oxlint --import-plugin --fix src test features stories"
31
31
  },
32
32
  "dependencies": {
33
- "@allurereport/charts-api": "3.16.0",
34
- "@allurereport/core-api": "3.16.0",
35
- "@allurereport/plugin-api": "3.16.0",
36
- "@allurereport/web-awesome": "3.16.0",
37
- "@allurereport/web-commons": "3.16.0",
33
+ "@allurereport/charts-api": "3.17.0",
34
+ "@allurereport/core-api": "3.17.0",
35
+ "@allurereport/plugin-api": "3.17.0",
36
+ "@allurereport/web-commons": "3.17.0",
38
37
  "d3-shape": "^3.2.0",
39
38
  "handlebars": "^4.7.9",
40
39
  "markdown-it": "^14.2.0"
41
40
  },
42
41
  "devDependencies": {
42
+ "@allurereport/web-awesome": "3.17.0",
43
43
  "@types/d3-shape": "^3.1.8",
44
44
  "@types/markdown-it": "^14.1.2",
45
45
  "@types/node": "^20",