Skip to content
Merged
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
1 change: 1 addition & 0 deletions .pnp.cjs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion packages/core/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,5 @@ export interface FullConfig {
url?: string;
project?: string;
accessToken?: string;
publish?: boolean;
};
}
54 changes: 27 additions & 27 deletions packages/core/src/report.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import type {
ReportFiles,
ResultFile,
} from "@allurereport/plugin-api";
import AwesomePlugin from "@allurereport/plugin-awesome";
import { allure1, allure2, attachments, cucumberjson, junitXml, readXcResultBundle } from "@allurereport/reader";
import { PathResultFile, type ResultsReader } from "@allurereport/reader-api";
import { AllureRemoteHistory, AllureServiceClient, KnownError, UnknownError } from "@allurereport/service";
Expand Down Expand Up @@ -43,7 +42,7 @@ export class AllureReport {
readonly #output: string;
readonly #history: AllureHistory | undefined;
readonly #allureServiceClient: AllureServiceClient | undefined;
readonly #publish: boolean;

#reportUrl?: string;
#state?: Record<string, PluginState>;
#stage: "init" | "running" | "done" = "init";
Expand All @@ -66,7 +65,6 @@ export class AllureReport {
} = opts;

this.#allureServiceClient = allureServiceConfig?.url ? new AllureServiceClient(allureServiceConfig) : undefined;
this.#publish = allureServiceConfig?.publish ?? false;
this.#reportUuid = randomUUID();
this.#reportName = name;
this.#eventEmitter = new EventEmitter<AllureStoreEvents>();
Expand Down Expand Up @@ -111,6 +109,10 @@ export class AllureReport {
return this.#qualityGate.result;
}

get #publish() {
return this.#plugins.some(({ enabled, options }) => enabled && options.publish);
}

readDirectory = async (resultsDir: string) => {
if (this.#stage !== "running") {
throw new Error(initRequired);
Expand Down Expand Up @@ -216,28 +218,28 @@ export class AllureReport {
// closing it early, to prevent future reads
this.#stage = "done";

await this.#eachPlugin(false, async (plugin, context, id) => {
const pluginFiles = (await context.state.get("files")) ?? {};

await this.#eachPlugin(false, async (plugin, context, { id, publish }) => {
await plugin.done?.(context, this.#store);

// publish only Allure Awesome reports
if (
plugin instanceof AwesomePlugin &&
this.#history &&
this.#allureServiceClient &&
this.#publish &&
Object.keys(pluginFiles).length
) {
await Promise.all(
Object.entries(pluginFiles).map(([key, filepath]) =>
this.#allureServiceClient?.addReportFile({
if (this.#allureServiceClient && publish) {
const pluginFiles = (await context.state.get("files")) ?? {};

for (const [filename, filepath] of Object.entries(pluginFiles)) {
// publish data-files separately
if (/^(data|widgets|index\.html$)/.test(filename)) {
this.#allureServiceClient.addReportFile({
reportUuid: this.#reportUuid,
key,
pluginId: id,
filename,
filepath,
});
} else {
this.#allureServiceClient.addReportAsset({
filename,
filepath,
}),
),
);
});
}
}
}

const summary = await plugin?.info?.(context, this.#store);
Expand Down Expand Up @@ -313,20 +315,18 @@ export class AllureReport {

#eachPlugin = async (
initState: boolean,
consumer: (plugin: Plugin, context: PluginContext, id: string) => Promise<void>,
consumer: (plugin: Plugin, context: PluginContext, options: { id: string; publish: boolean }) => Promise<void>,
) => {
if (initState) {
// reset state on start;
this.#state = {};
}

for (const descriptor of this.#plugins) {
if (!descriptor.enabled) {
for (const { enabled, id, plugin, options } of this.#plugins) {
if (!enabled) {
continue;
}

const id = descriptor.id;
const plugin = descriptor.plugin;
const pluginState = this.#getPluginState(initState, id);

if (!pluginState) {
Expand Down Expand Up @@ -357,7 +357,7 @@ export class AllureReport {
};

try {
await consumer.call(this, plugin, pluginContext, id);
await consumer.call(this, plugin, pluginContext, { id, publish: !!options?.publish });

if (initState) {
this.#state![id] = pluginState;
Expand Down
10 changes: 6 additions & 4 deletions packages/e2e/test/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import AwesomePlugin from "@allurereport/plugin-awesome";
import { serve } from "@allurereport/static-server";
import type { TestResult } from "allure-js-commons";
import { FileSystemWriter, ReporterRuntime } from "allure-js-commons/sdk/reporter";
import { randomUUID } from "node:crypto";
import { existsSync } from "node:fs";
import { mkdtemp, rm, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { resolve } from "node:path";
import { existsSync } from "node:fs";
import { randomUUID } from "node:crypto";

export type GeneratorParams = {
history?: HistoryDataPoint[];
Expand Down Expand Up @@ -37,21 +37,23 @@ export const randomNumber = (min: number, max: number): number => {

export const generateReport = async (payload: GeneratorParams) => {
const { reportConfig, rootDir, reportDir, resultsDir, testResults, attachments = [], history = [] } = payload;

const hasHistory = history.length > 0;
const historyPath = resolve(rootDir, `history-${randomUUID()}.jsonl`);

if (!existsSync(historyPath)) {
await writeFile(historyPath, "");
}

if (history.length > 0) {
if (hasHistory) {
await writeFile(historyPath, history.map((item) => JSON.stringify(item)).join("\n"), { encoding: "utf-8" });
}

const report = new AllureReport({
...reportConfig,
output: reportDir,
reportFiles: new FileSystemReportFiles(reportDir),
historyPath,
historyPath: hasHistory ? historyPath : undefined,
});
const runtime = new ReporterRuntime({
writer: new FileSystemWriter({
Expand Down
1 change: 0 additions & 1 deletion packages/plugin-api/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ export interface Config {
url?: string;
project?: string;
accessToken?: string;
publish?: boolean;
};
}

Expand Down
1 change: 1 addition & 0 deletions packages/plugin-awesome/src/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export type AwesomeOptions = {
charts?: ChartOptions[];
sections?: string[];
defaultSection?: string;
publish?: boolean;
};

export type TemplateManifest = Record<string, string>;
Expand Down
1 change: 1 addition & 0 deletions packages/sandbox/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"t": "yarn allure run -- vitest run"
},
"devDependencies": {
"@allurereport/plugin-awesome": "workspace:*",
"@allurereport/plugin-csv": "workspace:*",
"@stylistic/eslint-plugin": "^2.6.1",
"@types/eslint": "^8.56.11",
Expand Down
1 change: 1 addition & 0 deletions packages/service/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export type * from "./model.js";
export * from "./service.js";
export * from "./history.js";
export { KnownError, UnknownError } from "./utils/http.js";
67 changes: 61 additions & 6 deletions packages/service/src/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,19 +161,74 @@ export class AllureServiceClient {
return this.#client.post<{ url: string }>("/api/reports/create", {
body: {
project: this.project,
name: reportName,
reportName,
reportUuid,
},
});
}

/**
* Marks report as a completed one
* Use when all report files have been uploaded
* @param payload
*/
async completeReport(payload: { reportUuid: string }) {
const { reportUuid } = payload;

if (!this.project) {
throw new Error("Project is not set");
}

return this.#client.post("/api/reports/complete", {
body: {
id: reportUuid,
},
});
}

/**
* Uploads report asset which can be shared between multiple reports at once
* @param payload
*/
async addReportAsset(payload: { filename: string; file?: Buffer; filepath?: string }) {
const { filename, file, filepath } = payload;

if (!file && !filepath) {
throw new Error("File or filepath is required");
}

let content = file;

if (!content) {
content = await readFile(filepath!);
}

const form = new FormData();

form.set("filename", filename);
form.set("file", content);

return this.#client.post("/api/assets/upload", {
body: form,
headers: {
"Content-Type": "multipart/form-data",
},
});
}

/**
* Adds a file to an existing report
* If the report doesn't exist, it will be created
* @param payload
*/
async addReportFile(payload: { reportUuid: string; key: string; file?: Buffer; filepath?: string }) {
const { reportUuid, key, file, filepath } = payload;
async addReportFile(payload: {
reportUuid: string;
pluginId: string;
filename: string;
file?: Buffer;
filepath?: string;
}) {
const { reportUuid, filename, file, filepath, pluginId } = payload;

if (!file && !filepath) {
throw new Error("File or filepath is required");
Expand All @@ -187,8 +242,8 @@ export class AllureServiceClient {

const form = new FormData();

form.set("report", reportUuid);
form.set("filename", key);
form.set("reportUuid", reportUuid);
form.set("filename", joinPosix(pluginId, filename));
form.set("file", content);

await this.#client.post("/api/reports/upload", {
Expand All @@ -198,6 +253,6 @@ export class AllureServiceClient {
},
});

return joinPosix(this.#url, reportUuid, key);
return joinPosix(this.#url, reportUuid, filename);
}
}
Loading