@dhlab/e2e-autogen
Version:
Google 스프레드시트 기반 시나리오를 Playwright 테스트 스텁 코드로 자동 생성하고, 테스트 실행 결과를 다시 시트에 업데이트하는 CLI 도구
131 lines (130 loc) • 7.21 kB
JavaScript
var _TestRegistry_instances, _TestRegistry_jsonReporterFile, _TestRegistry_matrix, _TestRegistry_googleSpreadsheets, _TestRegistry_writeSuiteResults, _TestRegistry_addManualOnlyComments, _TestRegistry_resultColumnIndex, _TestRegistry_json, _TestRegistry_formatDate;
Object.defineProperty(exports, "__esModule", { value: true });
exports.TestRegistry = void 0;
const tslib_1 = require("tslib");
const chalk_1 = tslib_1.__importDefault(require("chalk"));
const fs = tslib_1.__importStar(require("fs-extra"));
const results_matrix_1 = require("./results-matrix");
class TestRegistry {
constructor(jsonReporterFile, googleSpreadsheets) {
_TestRegistry_instances.add(this);
_TestRegistry_jsonReporterFile.set(this, void 0);
_TestRegistry_matrix.set(this, void 0);
_TestRegistry_googleSpreadsheets.set(this, void 0);
tslib_1.__classPrivateFieldSet(this, _TestRegistry_jsonReporterFile, jsonReporterFile, "f");
tslib_1.__classPrivateFieldSet(this, _TestRegistry_matrix, new results_matrix_1.ResultsMatrix(), "f");
tslib_1.__classPrivateFieldSet(this, _TestRegistry_googleSpreadsheets, googleSpreadsheets, "f");
}
async logResults(resultsPerSuite) {
const suitesMeta = await tslib_1.__classPrivateFieldGet(this, _TestRegistry_googleSpreadsheets, "f").suitesMeta();
for (const [suiteId, resultPerTestId] of resultsPerSuite) {
const meta = suitesMeta.get(suiteId);
if (!meta) {
console.warn(`⚠️ '[${suiteId}]' 시트를 찾지 못해 스킵합니다.`);
continue;
}
const sheet = tslib_1.__classPrivateFieldGet(this, _TestRegistry_googleSpreadsheets, "f").testSuiteSheet(meta.gid);
await tslib_1.__classPrivateFieldGet(this, _TestRegistry_instances, "m", _TestRegistry_writeSuiteResults).call(this, sheet, resultPerTestId);
}
console.log(chalk_1.default.green("🎉 모든 테스트 결과 업데이트가 완료되었습니다!"));
console.log(chalk_1.default.blue(`🔗 ${tslib_1.__classPrivateFieldGet(this, _TestRegistry_googleSpreadsheets, "f").fullUrl}`));
}
async resultsPerSuite() {
const json = await tslib_1.__classPrivateFieldGet(this, _TestRegistry_instances, "m", _TestRegistry_json).call(this);
const base = tslib_1.__classPrivateFieldGet(this, _TestRegistry_matrix, "f").resultsPerSuite(json);
// 보강: 시트에 존재하지만 실행되지 않은 TC를 not_executed 로 채운다.
const suitesMeta = await tslib_1.__classPrivateFieldGet(this, _TestRegistry_googleSpreadsheets, "f").suitesMeta();
for (const [suiteId, meta] of suitesMeta) {
const sheet = tslib_1.__classPrivateFieldGet(this, _TestRegistry_googleSpreadsheets, "f").testSuiteSheet(meta.gid);
const rows = await sheet.rows();
const testIdCol = sheet.columnNumberOf("testId");
const tcIdsInSheet = rows
.slice(2) // 헤더 2줄 제외
.map((row) => row[testIdCol])
.filter(Boolean);
const bucket = base.get(suiteId) ?? new Map();
tcIdsInSheet.forEach((tcId) => {
if (!bucket.has(tcId)) {
bucket.set(tcId, { status: "not_executed" });
}
});
base.set(suiteId, bucket);
}
return base;
}
}
exports.TestRegistry = TestRegistry;
_TestRegistry_jsonReporterFile = new WeakMap(), _TestRegistry_matrix = new WeakMap(), _TestRegistry_googleSpreadsheets = new WeakMap(), _TestRegistry_instances = new WeakSet(), _TestRegistry_writeSuiteResults =
/** 시트 한 개에 대한 결과 기록 전체 프로세스 */
async function _TestRegistry_writeSuiteResults(sheet, resultPerTestId) {
if (resultPerTestId.size === 0)
return;
// 시트 데이터 로드
const rows = await sheet.rows();
const dataRows = rows.slice(2); // 헤더 제외
// (1) 결과값 배열 생성
const resultValues = dataRows.map((row) => {
const testId = row[sheet.columnNumberOf("testId")] ?? "";
const result = resultPerTestId.get(testId);
return [result ? tslib_1.__classPrivateFieldGet(this, _TestRegistry_matrix, "f").labelOf(result.status) : ""];
});
// (2) 헤더 + 결과 합치기 후 작성
const now = tslib_1.__classPrivateFieldGet(this, _TestRegistry_instances, "m", _TestRegistry_formatDate).call(this, new Date());
const columnValues = [
["자동테스트 결과"],
[now],
...resultValues,
];
const statuses = [
"pass",
"fail",
"flaky",
"not_executed",
"manual_only",
];
const statusLabels = statuses.map((s) => tslib_1.__classPrivateFieldGet(this, _TestRegistry_matrix, "f").labelOf(s));
const colIdx = tslib_1.__classPrivateFieldGet(this, _TestRegistry_instances, "m", _TestRegistry_resultColumnIndex).call(this, rows[0] ?? []);
await sheet.appendResultColumn(columnValues, statusLabels, rows.length, colIdx);
// (3) manual_only에 대한 description을 comment로 추가
await tslib_1.__classPrivateFieldGet(this, _TestRegistry_instances, "m", _TestRegistry_addManualOnlyComments).call(this, sheet, resultPerTestId, colIdx);
}, _TestRegistry_addManualOnlyComments =
/** manual_only에 대한 description을 comment로 추가 */
async function _TestRegistry_addManualOnlyComments(sheet, resultPerTestId, colIdx) {
const rows = await sheet.rows();
const testIdCol = sheet.columnNumberOf("testId");
for (let rowIdx = 2; rowIdx < rows.length; rowIdx++) {
// 헤더 2줄 제외
const testId = rows[rowIdx][testIdCol];
if (!testId)
continue;
const result = resultPerTestId.get(testId);
if (result?.status === "manual_only" && result.description) {
// comment 추가 (rowIdx는 0-based, 시트는 1-based이므로 +1)
await sheet.addComment(rowIdx + 1, colIdx + 1, result.description);
}
}
}, _TestRegistry_resultColumnIndex = function _TestRegistry_resultColumnIndex(headerRow) {
let lastIdx = 0;
for (let i = 0; i < headerRow.length; i++) {
const cell = headerRow[i];
if (cell && cell.toString().trim() !== "")
lastIdx = i;
}
return lastIdx + 1;
}, _TestRegistry_json = async function _TestRegistry_json() {
try {
const raw = await fs.readFile(tslib_1.__classPrivateFieldGet(this, _TestRegistry_jsonReporterFile, "f"), "utf8");
return JSON.parse(raw);
}
catch (error) {
throw new Error(`❌ ${tslib_1.__classPrivateFieldGet(this, _TestRegistry_jsonReporterFile, "f")} 파일 읽기 실패: ${error}`);
}
}, _TestRegistry_formatDate = function _TestRegistry_formatDate(date) {
const yyyy = date.getFullYear();
const mm = String(date.getMonth() + 1).padStart(2, "0");
const dd = String(date.getDate()).padStart(2, "0");
const hh = String(date.getHours()).padStart(2, "0");
const mi = String(date.getMinutes()).padStart(2, "0");
return `${yyyy}${mm}${dd}:${hh}:${mi}`;
};
tslib_1.__exportStar(require("./types"), exports);