Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 103 additions & 0 deletions docs/summary.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# Allure Summary

**Allure Summary** provides a short overview of a plugin execution. It also can be used to represent any
test run data outside of Allure Report plugins, to make it compatible with the Allure ecosystem.

Now, Allure Summary is utilized for the following purposes:

- displaying plugins on the Allure Report Summary page
- producing output by [Allure Github Action](https://github.com/allure-framework/allure-action)
- building another kind of integration that may require brief test information

## Structure of the Allure Summary

```ts
// it's a short test result format that contains enough data to represent a test in the summary
export type SummaryTestResult = {
name: string;
id: string;
status: "passed" | "failed" | "broken" | "skipped" | "unknown";
duration: number;
}

export interface AllureSummary {
// link to the hosted report (for example, published to Allure Service)
remoteHref?: string;
// link to the job that produced the report (for example, CI job)
jobHref?: string;
// link to the pull request that triggered the job
pullRequestHref?: string;
// the report's name which displays on the summary page
name: string;
// overall statistics
stats: {
regressed?: number;
fixed?: number;
malfunctioned?: number;
new?: number;
failed?: number;
broken?: number;
passed?: number;
skipped?: number;
unknown?: number;
total: number;
retries?: number;
flaky?: number;
};
// the worst test result status
status: "passed" | "failed" | "broken" | "skipped" | "unknown";
// total test run duration in milliseconds
duration: number;
// the id of the plugin that generated the summary
plugin?: string;
// brief description of the test run
newTests?: SummaryTestResult[];
flakyTests?: SummaryTestResult[];
retryTests?: SummaryTestResult[];
// date when the plugin generated the output
createdAt?: number;
}
```

## Displaying the plugin's summary information

To make your plugin visible on the Allure Report Summary page or in the Allure GitHub action comment, you need to
Implement the `info` method in the plugin class that returns the `AllureSummary` object:

```ts
import { getWorstStatus } from "@allurereport/core-api";
import {
type AllureStore,
type Plugin,
type PluginContext,
type AllureSummary,
} from "@allurereport/plugin-api";

export class MyPlugin implements Plugin {
// ...

// typical implementation of the info method
async info(context: PluginContext, store: AllureStore): Promise<AllureSummary> {
const allTrs = (await store.allTestResults()).filter((tr) =>
this.options.filter ? this.options.filter(tr) : true,
);
const newTrs = await store.allNewTestResults();
const retryTrs = allTrs.filter((tr) => !!tr?.retries?.length);
const flakyTrs = allTrs.filter((tr) => !!tr?.flaky);
const duration = allTrs.reduce((acc, { duration: trDuration = 0 }) => acc + trDuration, 0);
const createdAt = allTrs.reduce((acc, { stop }) => Math.max(acc, stop || 0), 0);

return {
plugin: "My plugin",
name: this.options.reportName || context.reportName,
stats: await store.testsStatistic(this.options.filter),
status: getWorstStatus(allTrs.map(({ status }) => status)) ?? "passed",
newTests: newTrs.map(convertToSummaryTestResult),
flakyTests: flakyTrs.map(convertToSummaryTestResult),
retryTests: retryTrs.map(convertToSummaryTestResult),
duration,
createdAt,
};
}
}
```
4 changes: 2 additions & 2 deletions packages/core/src/report.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ import type {
import {
type AllureStoreDump,
AllureStoreDumpFiles,
type AllureSummary,
type Plugin,
type PluginContext,
type PluginState,
type PluginSummary,
type ReportFiles,
type ResultFile,
} from "@allurereport/plugin-api";
Expand Down Expand Up @@ -457,7 +457,7 @@ export class AllureReport {
};

done = async (): Promise<void> => {
const summaries: PluginSummary[] = [];
const summaries: AllureSummary[] = [];
const remoteHrefs: string[] = [];

if (this.#executionStage !== "running") {
Expand Down
4 changes: 2 additions & 2 deletions packages/plugin-allure2/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import type { EnvironmentItem } from "@allurereport/core-api";
import { getWorstStatus } from "@allurereport/core-api";
import {
type AllureStore,
type AllureSummary,
type Plugin,
type PluginContext,
type PluginSummary,
convertToSummaryTestResult,
preciseTreeLabels,
} from "@allurereport/plugin-api";
Expand Down Expand Up @@ -101,7 +101,7 @@ export class Allure2Plugin implements Plugin {
});
};

async info(context: PluginContext, store: AllureStore): Promise<PluginSummary> {
async info(context: PluginContext, store: AllureStore): Promise<AllureSummary> {
const allTrs = await store.allTestResults();
const newTrs = await store.allNewTestResults();
const retryTrs = allTrs.filter((tr) => !!tr?.retries?.length);
Expand Down
4 changes: 2 additions & 2 deletions packages/plugin-api/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export interface PluginContext {
*/
export type SummaryTestResult = Pick<TestResult, "name" | "id" | "status" | "duration">;

export interface PluginSummary {
export interface AllureSummary {
href?: string;
remoteHref?: string;
jobHref?: string;
Expand Down Expand Up @@ -121,5 +121,5 @@ export interface Plugin {

done?(context: PluginContext, store: AllureStore): Promise<void>;

info?(context: PluginContext, store: AllureStore): Promise<PluginSummary>;
info?(context: PluginContext, store: AllureStore): Promise<AllureSummary>;
}
4 changes: 2 additions & 2 deletions packages/plugin-awesome/src/plugin.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { type EnvironmentItem, type Statistic, getWorstStatus } from "@allurereport/core-api";
import {
type AllureStore,
type AllureSummary,
type Plugin,
type PluginContext,
type PluginSummary,
convertToSummaryTestResult,
} from "@allurereport/plugin-api";
import { preciseTreeLabels } from "@allurereport/plugin-api";
Expand Down Expand Up @@ -141,7 +141,7 @@ export class AwesomePlugin implements Plugin {
await this.#generate(context, store);
};

async info(context: PluginContext, store: AllureStore): Promise<PluginSummary> {
async info(context: PluginContext, store: AllureStore): Promise<AllureSummary> {
const allTrs = (await store.allTestResults()).filter((tr) =>
this.options.filter ? this.options.filter(tr) : true,
);
Expand Down
4 changes: 2 additions & 2 deletions packages/plugin-classic/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import type { EnvironmentItem } from "@allurereport/core-api";
import { getWorstStatus } from "@allurereport/core-api";
import {
type AllureStore,
type AllureSummary,
type Plugin,
type PluginContext,
type PluginSummary,
convertToSummaryTestResult,
} from "@allurereport/plugin-api";
import { preciseTreeLabels } from "@allurereport/plugin-api";
Expand Down Expand Up @@ -108,7 +108,7 @@ export class ClassicPlugin implements Plugin {
await this.#generate(context, store);
};

async info(context: PluginContext, store: AllureStore): Promise<PluginSummary> {
async info(context: PluginContext, store: AllureStore): Promise<AllureSummary> {
const allTrs = (await store.allTestResults()).filter(this.options.filter ? this.options.filter : () => true);
const newTrs = await store.allNewTestResults();
const retryTrs = allTrs.filter((tr) => !!tr?.retries?.length);
Expand Down
4 changes: 2 additions & 2 deletions packages/plugin-dashboard/src/plugin.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { getWorstStatus } from "@allurereport/core-api";
import {
type AllureStore,
type AllureSummary,
type Plugin,
type PluginContext,
type PluginSummary,
convertToSummaryTestResult,
} from "@allurereport/plugin-api";
import { generateAllCharts, generateEnvirontmentsList, generateStaticFiles } from "./generators.js";
Expand Down Expand Up @@ -55,7 +55,7 @@ export class DashboardPlugin implements Plugin {
await this.#generate(context, store);
};

async info(context: PluginContext, store: AllureStore): Promise<PluginSummary> {
async info(context: PluginContext, store: AllureStore): Promise<AllureSummary> {
const allTrs = (await store.allTestResults()).filter(this.options.filter ? this.options.filter : () => true);
const newTrs = await store.allNewTestResults();
const retryTrs = allTrs.filter((tr) => !!tr?.retries?.length);
Expand Down
4 changes: 2 additions & 2 deletions packages/summary/src/generators.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { createBaseUrlScript, createScriptTag } from "@allurereport/core-api";
import type { PluginSummary } from "@allurereport/plugin-api";
import type { AllureSummary } from "@allurereport/plugin-api";
import Handlebars from "handlebars";
import { readFile } from "node:fs/promises";
import { createRequire } from "node:module";
Expand Down Expand Up @@ -37,7 +37,7 @@ export const readTemplateManifest = async (): Promise<TemplateManifest> => {
return JSON.parse(templateManifest);
};

export const generateSummaryStaticFiles = async (payload: { summaries: PluginSummary[] }) => {
export const generateSummaryStaticFiles = async (payload: { summaries: AllureSummary[] }) => {
const compile = Handlebars.compile(template);
const manifest = await readTemplateManifest();
const bodyTags: string[] = [];
Expand Down
4 changes: 2 additions & 2 deletions packages/summary/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { PluginSummary } from "@allurereport/plugin-api";
import type { AllureSummary } from "@allurereport/plugin-api";
import { writeFile } from "node:fs/promises";
import { resolve } from "node:path";
import { generateSummaryStaticFiles } from "./generators.js";
Expand All @@ -8,7 +8,7 @@ import { generateSummaryStaticFiles } from "./generators.js";
* @param output
* @param summaries
*/
export const generateSummary = async (output: string, summaries: PluginSummary[]) => {
export const generateSummary = async (output: string, summaries: AllureSummary[]) => {
if (!summaries.length) {
return undefined;
}
Expand Down