Skip to content

Commit 56f152b

Browse files
committed
deploy: 51edaf8
1 parent b59611a commit 56f152b

13 files changed

Lines changed: 331 additions & 1 deletion

index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ <h1>💻 FASTFIVE WEB 자동화 테스트</h1>
102102
</div>
103103
<script>
104104
const productionHistory = [];
105-
const stagingHistory = [{"run_id":"24174799586","status":"✅ 성공","status_class":"success","timestamp":"2026-04-09 14:54:49","env":"staging"},{"run_id":"22173244445","status":"✅ 성공","status_class":"success","timestamp":"2026-02-19 16:58:07","env":"staging"},{"run_id":"22173010350","status":"❌ 실패","status_class":"failure","timestamp":"2026-02-19 16:49:34","env":"staging"},{"run_id":"22172626085","status":"❌ 실패","status_class":"failure","timestamp":"2026-02-19 16:34:52","env":"staging"},{"run_id":"22164851417","status":"❌ 실패","status_class":"failure","timestamp":"2026-02-19 10:33:24","env":"staging"},{"run_id":"22030950132","status":"❌ 실패","status_class":"failure","timestamp":"2026-02-15 15:22:53","env":"staging"},{"run_id":"22030826080","status":"❌ 실패","status_class":"failure","timestamp":"2026-02-15 15:10:00","env":"staging"},{"run_id":"21692615946","status":"✅ 성공","status_class":"success","timestamp":"2026-02-05 08:39:30","env":"staging"},{"run_id":"21239979091","status":"✅ 성공","status_class":"success","timestamp":"2026-01-22 16:36:26","env":"staging"},{"run_id":"21236186304","status":"✅ 성공","status_class":"success","timestamp":"2026-01-22 13:37:24","env":"staging"},{"run_id":"21236000045","status":"✅ 성공","status_class":"success","timestamp":"2026-01-22 13:27:42","env":"staging"},{"run_id":"21235759842","status":"✅ 성공","status_class":"success","timestamp":"2026-01-22 13:15:25","env":"staging"},{"run_id":"21235074311","status":"✅ 성공","status_class":"success","timestamp":"2026-01-22 12:39:34","env":"staging"},{"run_id":"21234121201","status":"✅ 성공","status_class":"success","timestamp":"2026-01-22 11:50:36","env":"staging"},{"run_id":"21234078897","status":"✅ 성공","status_class":"success","timestamp":"2026-01-22 11:48:30","env":"staging"},{"run_id":"21231883401","status":"✅ 성공","status_class":"success","timestamp":"2026-01-22 10:05:12","env":"staging"},{"run_id":"21230970147","status":"✅ 성공","status_class":"success","timestamp":"2026-01-22 09:26:35","env":"staging"},{"run_id":"21201864641","status":"✅ 성공","status_class":"success","timestamp":"2026-01-21 17:08:48","env":"staging"},{"run_id":"21194400505","status":"❌ 실패","status_class":"failure","timestamp":"2026-01-21 11:01:01","env":"staging"},{"run_id":"21057740383","status":"✅ 성공","status_class":"success","timestamp":"2026-01-16 15:26:50","env":"staging"},{"run_id":"21057527636","status":"✅ 성공","status_class":"success","timestamp":"2026-04-09 14:54:59","env":"staging"},{"run_id":"21053369252","status":"✅ 성공","status_class":"success","timestamp":"2026-04-09 14:54:59","env":"staging"},{"run_id":"21053291432","status":"❌ 실패","status_class":"failure","timestamp":"2026-04-09 14:54:59","env":"staging"},{"run_id":"21053192419","status":"✅ 성공","status_class":"success","timestamp":"2026-04-09 14:54:59","env":"staging"},{"run_id":"21052989177","status":"✅ 성공","status_class":"success","timestamp":"2026-04-09 14:54:59","env":"staging"},{"run_id":"21052650770","status":"✅ 성공","status_class":"success","timestamp":"2026-04-09 14:54:59","env":"staging"},{"run_id":"21052326789","status":"❌ 실패","status_class":"failure","timestamp":"2026-04-09 14:54:59","env":"staging"},{"run_id":"21022342757","status":"❌ 실패","status_class":"failure","timestamp":"2026-04-09 14:54:59","env":"staging"},{"run_id":"21022171287","status":"❌ 실패","status_class":"failure","timestamp":"2026-04-09 14:54:59","env":"staging"},{"run_id":"21021965993","status":"✅ 성공","status_class":"success","timestamp":"2026-04-09 14:54:59","env":"staging"},{"run_id":"21021877528","status":"✅ 성공","status_class":"success","timestamp":"2026-04-09 14:54:59","env":"staging"}];
105+
const stagingHistory = [{"run_id":"24175047314","status":"✅ 성공","status_class":"success","timestamp":"2026-04-09 15:02:56","env":"staging"},{"run_id":"24174799586","status":"✅ 성공","status_class":"success","timestamp":"2026-04-09 14:54:49","env":"staging"},{"run_id":"22173244445","status":"✅ 성공","status_class":"success","timestamp":"2026-02-19 16:58:07","env":"staging"},{"run_id":"22173010350","status":"❌ 실패","status_class":"failure","timestamp":"2026-02-19 16:49:34","env":"staging"},{"run_id":"22172626085","status":"❌ 실패","status_class":"failure","timestamp":"2026-02-19 16:34:52","env":"staging"},{"run_id":"22164851417","status":"❌ 실패","status_class":"failure","timestamp":"2026-02-19 10:33:24","env":"staging"},{"run_id":"22030950132","status":"❌ 실패","status_class":"failure","timestamp":"2026-02-15 15:22:53","env":"staging"},{"run_id":"22030826080","status":"❌ 실패","status_class":"failure","timestamp":"2026-02-15 15:10:00","env":"staging"},{"run_id":"21692615946","status":"✅ 성공","status_class":"success","timestamp":"2026-02-05 08:39:30","env":"staging"},{"run_id":"21239979091","status":"✅ 성공","status_class":"success","timestamp":"2026-01-22 16:36:26","env":"staging"},{"run_id":"21236186304","status":"✅ 성공","status_class":"success","timestamp":"2026-01-22 13:37:24","env":"staging"},{"run_id":"21236000045","status":"✅ 성공","status_class":"success","timestamp":"2026-01-22 13:27:42","env":"staging"},{"run_id":"21235759842","status":"✅ 성공","status_class":"success","timestamp":"2026-01-22 13:15:25","env":"staging"},{"run_id":"21235074311","status":"✅ 성공","status_class":"success","timestamp":"2026-01-22 12:39:34","env":"staging"},{"run_id":"21234121201","status":"✅ 성공","status_class":"success","timestamp":"2026-01-22 11:50:36","env":"staging"},{"run_id":"21234078897","status":"✅ 성공","status_class":"success","timestamp":"2026-01-22 11:48:30","env":"staging"},{"run_id":"21231883401","status":"✅ 성공","status_class":"success","timestamp":"2026-01-22 10:05:12","env":"staging"},{"run_id":"21230970147","status":"✅ 성공","status_class":"success","timestamp":"2026-01-22 09:26:35","env":"staging"},{"run_id":"21201864641","status":"✅ 성공","status_class":"success","timestamp":"2026-01-21 17:08:48","env":"staging"},{"run_id":"21194400505","status":"❌ 실패","status_class":"failure","timestamp":"2026-01-21 11:01:01","env":"staging"},{"run_id":"21057740383","status":"✅ 성공","status_class":"success","timestamp":"2026-01-16 15:26:50","env":"staging"},{"run_id":"21057527636","status":"✅ 성공","status_class":"success","timestamp":"2026-04-09 15:03:05","env":"staging"},{"run_id":"21053369252","status":"✅ 성공","status_class":"success","timestamp":"2026-04-09 15:03:05","env":"staging"},{"run_id":"21053291432","status":"❌ 실패","status_class":"failure","timestamp":"2026-04-09 15:03:05","env":"staging"},{"run_id":"21053192419","status":"✅ 성공","status_class":"success","timestamp":"2026-04-09 15:03:05","env":"staging"},{"run_id":"21052989177","status":"✅ 성공","status_class":"success","timestamp":"2026-04-09 15:03:05","env":"staging"},{"run_id":"21052650770","status":"✅ 성공","status_class":"success","timestamp":"2026-04-09 15:03:05","env":"staging"},{"run_id":"21052326789","status":"❌ 실패","status_class":"failure","timestamp":"2026-04-09 15:03:05","env":"staging"},{"run_id":"21022342757","status":"❌ 실패","status_class":"failure","timestamp":"2026-04-09 15:03:05","env":"staging"},{"run_id":"21022171287","status":"❌ 실패","status_class":"failure","timestamp":"2026-04-09 15:03:05","env":"staging"},{"run_id":"21021965993","status":"✅ 성공","status_class":"success","timestamp":"2026-04-09 15:03:05","env":"staging"},{"run_id":"21021877528","status":"✅ 성공","status_class":"success","timestamp":"2026-04-09 15:03:05","env":"staging"}];
106106
const PAGE_SIZE = 10;
107107
let prodPage = 1, stagingPage = 1;
108108

staging/24175047314/branch.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
prd

staging/24175047314/env.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
staging

staging/24175047314/exit-code.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0

staging/24175047314/ffmpeg.log

Lines changed: 50 additions & 0 deletions
Large diffs are not rendered by default.

staging/24175047314/index.html

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
<!DOCTYPE html>
2+
<html lang="ko">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>테스트 결과 - 24175047314</title>
7+
<style>
8+
* { box-sizing: border-box; margin: 0; padding: 0; }
9+
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #f5f5f5; padding: 20px; }
10+
.container { max-width: 1200px; margin: 0 auto; }
11+
.header { background: white; padding: 30px; border-radius: 10px; margin-bottom: 20px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
12+
.header h1 { font-size: 24px; margin-bottom: 15px; }
13+
.meta { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px; }
14+
.meta-item { padding: 10px; background: #f8f9fa; border-radius: 5px; }
15+
.meta-item label { font-size: 12px; color: #666; display: block; }
16+
.meta-item span { font-size: 14px; font-weight: 500; }
17+
.status-badge { display: inline-block; padding: 5px 15px; border-radius: 20px; font-weight: bold; }
18+
.status-badge.success { background: #d4edda; color: #155724; }
19+
.status-badge.failure { background: #f8d7da; color: #721c24; }
20+
.status-badge.error { background: #f8d7da; color: #721c24; }
21+
.section { background: white; padding: 20px; border-radius: 10px; margin-bottom: 20px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
22+
.section h2 { font-size: 18px; margin-bottom: 15px; padding-bottom: 10px; border-bottom: 1px solid #eee; }
23+
video { width: 100%; max-height: 600px; background: #000; border-radius: 5px; }
24+
.log-content { background: #1e1e1e; color: #d4d4d4; padding: 15px; border-radius: 5px; font-family: 'Monaco', 'Consolas', monospace; font-size: 13px; overflow-x: auto; white-space: pre-wrap; max-height: 500px; overflow-y: auto; }
25+
.back-link { display: inline-block; margin-bottom: 20px; color: #007bff; text-decoration: none; }
26+
.back-link:hover { text-decoration: underline; }
27+
.screenshots { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 15px; }
28+
.screenshot { border: 1px solid #ddd; border-radius: 5px; overflow: hidden; }
29+
.screenshot img { width: 100%; }
30+
.screenshot p { padding: 10px; background: #f8f9fa; font-size: 12px; }
31+
.test-results { border: 1px solid #eee; border-radius: 8px; overflow: hidden; }
32+
.test-item { display: flex; align-items: center; padding: 15px; border-bottom: 1px solid #eee; gap: 15px; }
33+
.test-item:last-child { border-bottom: none; }
34+
.test-item.success { background: #f8fff8; }
35+
.test-item.failure, .test-item.error { background: #fff8f8; }
36+
.test-icon { font-size: 20px; }
37+
.test-info { flex: 1; }
38+
.test-name { font-weight: 600; font-size: 14px; }
39+
.test-message { font-size: 12px; color: #c00; margin-top: 4px; word-break: break-all; }
40+
.test-duration { font-size: 12px; color: #888; white-space: nowrap; }
41+
.test-traceback { font-size: 11px; color: #666; margin-top: 8px; background: #f8f8f8; padding: 10px; border-radius: 4px; font-family: monospace; white-space: pre-wrap; max-height: 200px; overflow-y: auto; }
42+
.test-screenshot { margin-top: 10px; }
43+
.test-screenshot img { max-width: 300px; border: 1px solid #ddd; border-radius: 4px; cursor: pointer; }
44+
.test-screenshot img:hover { border-color: #007bff; }
45+
</style>
46+
</head>
47+
<body>
48+
<div class="container">
49+
<a href="../../" class="back-link">← 전체 히스토리로 돌아가기</a>
50+
<div class="header">
51+
<h1>테스트 결과 <span class="status-badge success">✅ 성공</span></h1>
52+
<div class="meta">
53+
<div class="meta-item"><label>Run ID</label><span>24175047314</span></div>
54+
<div class="meta-item"><label>환경</label><span>스테이징</span></div>
55+
<div class="meta-item"><label>테스트 URL</label><span><a href="https://members-staging.slowfive.com/" target="_blank" style="color:#007bff;text-decoration:none;">https://members-staging.slowfive.com/</a></span></div>
56+
<div class="meta-item"><label>Branch</label><span>prd</span></div>
57+
<div class="meta-item"><label>Commit</label><span>51edaf8</span></div>
58+
<div class="meta-item"><label>실행 시간</label><span>2026-04-09 15:02:56</span></div>
59+
</div>
60+
</div>
61+
62+
<div class="section">
63+
<h2>🧪 테스트별 결과</h2>
64+
<div id="test-summary" style="display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:10px;margin-bottom:15px;"></div>
65+
<div class="test-results" id="test-results">
66+
<p style="padding:20px;color:#666;">테스트 결과를 불러오는 중...</p>
67+
</div>
68+
</div>
69+
70+
<div class="section">
71+
<h2>🎬 테스트 녹화 영상</h2>
72+
<video controls>
73+
<source src="test-recording.mp4" type="video/mp4">
74+
영상을 재생할 수 없습니다.
75+
</video>
76+
</div>
77+
78+
<div class="section">
79+
<h2>📋 테스트 로그</h2>
80+
<pre class="log-content" id="log-content">로그를 불러오는 중...</pre>
81+
</div>
82+
83+
<div class="section">
84+
<h2>📸 스크린샷</h2>
85+
<div class="screenshots" id="screenshots"></div>
86+
</div>
87+
</div>
88+
<script>
89+
// 테스트별 결과 로드
90+
fetch('test-results.json').then(r => r.json()).then(results => {
91+
const container = document.getElementById('test-results');
92+
const summaryContainer = document.getElementById('test-summary');
93+
if (!results || results.length === 0) {
94+
container.innerHTML = '<p style="padding:20px;color:#666;">테스트 결과가 없습니다.</p>';
95+
return;
96+
}
97+
// 총 수행 결과 계산
98+
var total = results.length;
99+
var success = results.filter(function(r) { return r.status === 'success'; }).length;
100+
var failure = total - success;
101+
var totalSeconds = results.reduce(function(sum, r) { return sum + (r.duration || 0); }, 0);
102+
var rate = total > 0 ? Math.round((success / total) * 100) : 0;
103+
// 시/분/초 형식으로 변환
104+
function formatDuration(seconds) {
105+
var h = Math.floor(seconds / 3600);
106+
var m = Math.floor((seconds % 3600) / 60);
107+
var s = Math.floor(seconds % 60);
108+
var parts = [];
109+
if (h > 0) parts.push(h + '시간');
110+
if (m > 0) parts.push(m + '분');
111+
parts.push(s + '초');
112+
return parts.join(' ');
113+
}
114+
var durationText = formatDuration(totalSeconds);
115+
// 요약 카드 표시
116+
summaryContainer.innerHTML =
117+
'<div style="padding:15px;border-radius:8px;text-align:center;background:#e3f2fd;"><div style="font-size:28px;font-weight:bold;color:#1565c0;">' + total + '</div><div style="font-size:12px;color:#666;">전체</div></div>' +
118+
'<div style="padding:15px;border-radius:8px;text-align:center;background:#e8f5e9;"><div style="font-size:28px;font-weight:bold;color:#2e7d32;">' + success + '</div><div style="font-size:12px;color:#666;">성공</div></div>' +
119+
'<div style="padding:15px;border-radius:8px;text-align:center;background:#ffebee;"><div style="font-size:28px;font-weight:bold;color:#c62828;">' + failure + '</div><div style="font-size:12px;color:#666;">실패</div></div>' +
120+
'<div style="padding:15px;border-radius:8px;text-align:center;background:#fff3e0;"><div style="font-size:28px;font-weight:bold;color:#ef6c00;">' + rate + '%</div><div style="font-size:12px;color:#666;">성공률</div></div>' +
121+
'<div style="padding:15px;border-radius:8px;text-align:center;background:#f3e5f5;"><div style="font-size:20px;font-weight:bold;color:#7b1fa2;">' + durationText + '</div><div style="font-size:12px;color:#666;">총 수행시간</div></div>';
122+
// 테스트 목록 표시
123+
container.innerHTML = results.map(function(r) {
124+
var icon = r.status === 'success' ? '✅' : '❌';
125+
var msgHtml = r.message ? '<div class="test-message">' + r.message + '</div>' : '';
126+
var traceHtml = r.traceback ? '<div class="test-traceback">' + r.traceback.replace(/</g, '&lt;').replace(/>/g, '&gt;') + '</div>' : '';
127+
var screenshotHtml = r.screenshot ? '<div class="test-screenshot"><a href="' + r.screenshot + '" target="_blank"><img src="' + r.screenshot + '" alt="실패 스크린샷"></a></div>' : '';
128+
return '<div class="test-item ' + r.status + '">' +
129+
'<span class="test-icon">' + icon + '</span>' +
130+
'<div class="test-info">' +
131+
'<div class="test-name">' + r.name + '</div>' +
132+
msgHtml +
133+
traceHtml +
134+
screenshotHtml +
135+
'</div>' +
136+
'<span class="test-duration">' + r.duration + 's</span>' +
137+
'</div>';
138+
}).join('');
139+
}).catch(function() {
140+
document.getElementById('test-results').innerHTML = '<p style="padding:20px;color:#666;">테스트 결과를 불러올 수 없습니다.</p>';
141+
});
142+
143+
fetch('test-output.log').then(r => r.text()).then(t => {
144+
document.getElementById('log-content').textContent = t || '로그가 없습니다.';
145+
}).catch(() => {
146+
document.getElementById('log-content').textContent = '로그를 불러올 수 없습니다.';
147+
});
148+
149+
// 동적으로 주입된 스크린샷 목록
150+
const pngs = ["request-before-submit.png","request-complete.png"];
151+
const container = document.getElementById('screenshots');
152+
if (pngs.length === 0) {
153+
container.innerHTML = '<p style="color:#666;">스크린샷이 없습니다.</p>';
154+
} else {
155+
pngs.forEach(png => {
156+
const div = document.createElement('div');
157+
div.className = 'screenshot';
158+
div.innerHTML = '<a href="' + png + '" target="_blank"><img src="' + png + '"></a><p>' + png + '</p>';
159+
container.appendChild(div);
160+
});
161+
}
162+
</script>
163+
</body>
164+
</html>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
url=https://members-staging.slowfive.com/sign-in
2+
title=FASTFIVE Members
3+
ready_state=complete
4+
navigator_webdriver=False
5+
user_agent=Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36
6+
app_inner_length=3504
7+
page_source_length=10416
87.9 KB
Loading
82.6 KB
Loading

0 commit comments

Comments
 (0)