Skip to content

Commit

Permalink
feat(experimental): video attachment upload
Browse files Browse the repository at this point in the history
  • Loading branch information
DamianOsipiuk committed Jun 11, 2021
1 parent 8528439 commit 729a251
Show file tree
Hide file tree
Showing 8 changed files with 154 additions and 28 deletions.
4 changes: 4 additions & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ export const prepareConfig = (options: Config = {} as Config): Config => {
process.env.TESTRAIL_UPLOAD_SCREENSHOTS == "true" ||
config.uploadScreenshots ||
false,
uploadVideos:
process.env.TESTRAIL_UPLOAD_VIDEOS == "true" ||
config.uploadVideos ||
false,
updateRunTestCases:
process.env.TESTRAIL_UPDATE_RUN_TEST_CASES == "true" ||
config.updateRunTestCases !== false,
Expand Down
59 changes: 32 additions & 27 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,20 @@ import moment from "moment";
import { TestRail, TestStatus, Run, AddResultForCase } from "testrail-js-api";

import { prepareConfig, verifyConfig } from "./config";
import { prepareReference, prepareReportName, throwOnApiError } from "./utils";
import {
prepareReference,
prepareReportName,
throwOnApiError,
uploadScreenshots,
uploadVideos,
} from "./utils";
import type {
Config,
Meta,
Screenshot,
TaskResult,
TestRunInfo,
Video,
} from "./types";

const Status = {
Expand Down Expand Up @@ -132,6 +139,9 @@ class TestcafeTestrailReporter {
screenshots: {
[key: string]: Screenshot[];
};
videos: {
[key: string]: Video[];
};

constructor() {
this.config = prepareConfig();
Expand All @@ -141,6 +151,7 @@ class TestcafeTestrailReporter {
this.noColors = false;
this.results = [];
this.screenshots = {};
this.videos = {};
}

reportTaskStart = async (_startTime: number, userAgents: string[]) => {
Expand Down Expand Up @@ -195,6 +206,9 @@ class TestcafeTestrailReporter {
if (testRunInfo.screenshots.length) {
this.screenshots[caseId] = testRunInfo.screenshots;
}
if (testRunInfo.videos?.length) {
this.videos[caseId] = testRunInfo.videos;
}
} else {
console.log(
`[TestRail] Test missing the TestRail Case ID in test metadata: ${name}`
Expand Down Expand Up @@ -266,32 +280,23 @@ class TestcafeTestrailReporter {
);
const { value: tests } = await throwOnApiError(testrailAPI.getTests(runId));

if (this.config.uploadScreenshots) {
console.log("[TestRail] Uploading screenshots...");
for (let i = 0; i < resultsToPush.length; i++) {
const test = tests.find(
(test) => test.case_id === resultsToPush[i].case_id
);
const result = results.find((result) => result.test_id === test?.id);
if (result) {
const screenshots = this.screenshots[resultsToPush[i].case_id];
if (screenshots) {
for (let j = 0; j < screenshots.length; j++) {
await throwOnApiError(
testrailAPI.addAttachmentToResult(
result.id,
screenshots[j].screenshotPath
)
);
}
}
} else {
console.error(
`[TestRail] Could not upload screenshot for a failed test. Case ID: ${resultsToPush[i].caseId}. Test ID: ${test?.id}`
);
}
}
}
uploadScreenshots({
config: this.config,
tests,
results,
resultsToPush,
screenshots: this.screenshots,
testrailAPI,
});

uploadVideos({
config: this.config,
tests,
results,
resultsToPush,
videos: this.videos,
testrailAPI,
});

if (results.length == 0) {
console.log("[TestRail] No data has been published to TestRail");
Expand Down
6 changes: 6 additions & 0 deletions src/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export interface Config<T = number> {
caseMeta: string;
runCloseAfterDays?: number;
uploadScreenshots: boolean;
uploadVideos: boolean;
updateRunTestCases: boolean;
}

Expand All @@ -36,13 +37,18 @@ export interface Screenshot {
takenOnFail: boolean;
}

export interface Video {
videoPath: string;
}

export interface TestRunInfo {
errs: Record<string, unknown>[];
warnings: string[];
durationMs: number;
unstable: boolean;
screenshotPath: string;
screenshots: Screenshot[];
videos: Video[];
quarantine: { [key: string]: { passed: boolean } };
skipped: boolean;
}
3 changes: 3 additions & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { uploadScreenshots } from "./upload-screenshots";
export { uploadVideos } from "./upload-videos";
export { prepareReference, prepareReportName, throwOnApiError } from "./utils";
51 changes: 51 additions & 0 deletions src/utils/upload-screenshots.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { TestRail, AddResultForCase, Test, Result } from "testrail-js-api";

import { throwOnApiError } from "../utils";
import type { Config, Screenshot } from "../types";

type UploadScreenshots = (options: {
config: Config;
tests: Test[];
results: Result[];
resultsToPush: AddResultForCase[];
screenshots: {
[key: string]: Screenshot[];
};
testrailAPI: TestRail;
}) => void;

export const uploadScreenshots: UploadScreenshots = async ({
config,
tests,
results,
resultsToPush,
screenshots,
testrailAPI,
}) => {
if (config.uploadScreenshots) {
console.log("[TestRail] Uploading screenshots...");
for (let i = 0; i < resultsToPush.length; i++) {
const test = tests.find(
(test) => test.case_id === resultsToPush[i].case_id
);
const result = results.find((result) => result.test_id === test?.id);
if (result) {
const screenshotList = screenshots[resultsToPush[i].case_id];
if (screenshotList) {
for (let j = 0; j < screenshotList.length; j++) {
await throwOnApiError(
testrailAPI.addAttachmentToResult(
result.id,
screenshotList[j].screenshotPath
)
);
}
}
} else {
console.error(
`[TestRail] Could not upload screenshot for a failed test. Case ID: ${resultsToPush[i].caseId}. Test ID: ${test?.id}`
);
}
}
}
};
51 changes: 51 additions & 0 deletions src/utils/upload-videos.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { TestRail, AddResultForCase, Test, Result } from "testrail-js-api";

import { throwOnApiError } from "../utils";
import type { Config, Video } from "../types";

type UploadVideos = (options: {
config: Config;
tests: Test[];
results: Result[];
resultsToPush: AddResultForCase[];
videos: {
[key: string]: Video[];
};
testrailAPI: TestRail;
}) => void;

export const uploadVideos: UploadVideos = async ({
config,
tests,
results,
resultsToPush,
videos,
testrailAPI,
}) => {
if (config.uploadVideos) {
console.log("[TestRail] Uploading videos...");
for (let i = 0; i < resultsToPush.length; i++) {
const test = tests.find(
(test) => test.case_id === resultsToPush[i].case_id
);
const result = results.find((result) => result.test_id === test?.id);
if (result) {
const videoList = videos[resultsToPush[i].case_id];
if (videoList) {
for (let j = 0; j < videoList.length; j++) {
await throwOnApiError(
testrailAPI.addAttachmentToResult(
result.id,
videoList[j].videoPath
)
);
}
}
} else {
console.error(
`[TestRail] Could not upload videos for a failed test. Case ID: ${resultsToPush[i].caseId}. Test ID: ${test?.id}`
);
}
}
}
};
2 changes: 1 addition & 1 deletion src/utils.ts → src/utils/utils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import moment from "moment";
import { Response } from "node-fetch";

import type { Config } from "./types";
import type { Config } from "../types";

export async function throwOnApiError<
T extends { response: Response; value: unknown }
Expand Down
6 changes: 6 additions & 0 deletions tests/config/prepareConfig.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const defaultConfig = {
suiteId: 0,
updateRunTestCases: true,
uploadScreenshots: false,
uploadVideos: false,
user: undefined,
};

Expand All @@ -46,6 +47,7 @@ const envConfig = {
TESTRAIL_CASE_META: "meta",
TESTRAIL_RUN_CLOSE_AFTER_DAYS: 111,
TESTRAIL_UPLOAD_SCREENSHOTS: "true",
TESTRAIL_UPLOAD_VIDEOS: "true",
TESTRAIL_UPDATE_RUN_TEST_CASES: "true",
};

Expand All @@ -66,6 +68,7 @@ const fileConfig = {
suiteId: "4444",
updateRunTestCases: true,
uploadScreenshots: false,
uploadVideos: false,
user: "user2",
};

Expand Down Expand Up @@ -144,6 +147,7 @@ describe("prepareConfig", () => {
suiteId: 234,
updateRunTestCases: true,
uploadScreenshots: true,
uploadVideos: true,
user: "user",
});
});
Expand All @@ -170,6 +174,7 @@ describe("prepareConfig", () => {
suiteId: 4444,
updateRunTestCases: true,
uploadScreenshots: false,
uploadVideos: false,
user: "user2",
});
});
Expand Down Expand Up @@ -197,6 +202,7 @@ describe("prepareConfig", () => {
suiteId: 234,
updateRunTestCases: true,
uploadScreenshots: true,
uploadVideos: true,
user: "user",
});
});
Expand Down

0 comments on commit 729a251

Please sign in to comment.