UNPKG

@dhlab/e2e-autogen

Version:

Google 스프레드시트 기반 시나리오를 Playwright 테스트 스텁 코드로 자동 생성하고, 테스트 실행 결과를 다시 시트에 업데이트하는 CLI 도구

133 lines (131 loc) 7.22 kB
'use strict'; 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);