Skip to content

Commit 0b168ed

Browse files
committed
deploy: 9a9e157
1 parent b347d49 commit 0b168ed

File tree

9 files changed

+224
-1
lines changed

9 files changed

+224
-1
lines changed

app-index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
</div>
5555
<script>
5656
const prodHistory = [];
57-
const stagingHistory = [{"run_id":"21349493647-ios","status":"❌ 실패","status_class":"failure","timestamp":"2026-01-26 16:23:28","platform":"ios"},{"run_id":"21349447163-android","status":"❌ 실패","status_class":"failure","timestamp":"2026-01-26 16:22:29","platform":"android"},{"run_id":"21349349274-android","status":"✅ 성공","status_class":"success","timestamp":"2026-01-26 16:21:12","platform":"android"},{"run_id":"21349347409-ios","status":"✅ 성공","status_class":"success","timestamp":"2026-01-26 16:16:30","platform":"ios"},{"run_id":"21349347409-android","status":"✅ 성공","status_class":"success","timestamp":"2026-01-26 16:18:46","platform":"android"},{"run_id":"21349227630-android","status":"✅ 성공","status_class":"success","timestamp":"2026-01-26 16:11:45","platform":"android"},{"run_id":"21349106806-android","status":"❌ 실패","status_class":"failure","timestamp":"2026-01-26 16:09:05","platform":"android"},{"run_id":"21349104503-ios","status":"✅ 성공","status_class":"success","timestamp":"2026-01-26 16:07:27","platform":"ios"},{"run_id":"21349104503-android","status":"✅ 성공","status_class":"success","timestamp":"2026-01-26 16:06:31","platform":"android"},{"run_id":"21349046528-android","status":"❌ 실패","status_class":"failure","timestamp":"2026-01-26 16:03:00","platform":"android"},{"run_id":"21348949966-android","status":"❌ 실패","status_class":"failure","timestamp":"2026-01-26 15:57:52","platform":"android"},{"run_id":"21348785037","status":"❌ 실패","status_class":"failure","timestamp":"2026-01-26 15:49:23","platform":"android"},{"run_id":"21348753276","status":"✅ 성공","status_class":"success","timestamp":"2026-01-26 15:47:18","platform":"android"},{"run_id":"21329397942","status":"❌ 실패","status_class":"failure","timestamp":"2026-01-25 23:07:26","platform":"android"},{"run_id":"21279731003","status":"✅ 성공","status_class":"success","timestamp":"2026-01-23 17:32:02","platform":"android"},{"run_id":"21240824573","status":"✅ 성공","status_class":"success","timestamp":"2026-01-22 17:09:15","platform":"android"},{"run_id":"21240728460","status":"✅ 성공","status_class":"success","timestamp":"2026-01-22 17:05:14","platform":"android"},{"run_id":"21237795149","status":"✅ 성공","status_class":"success","timestamp":"2026-01-22 14:57:17","platform":"android"},{"run_id":"21237696679","status":"✅ 성공","status_class":"success","timestamp":"2026-01-22 14:52:30","platform":"android"},{"run_id":"21237534475","status":"✅ 성공","status_class":"success","timestamp":"2026-01-22 14:44:29","platform":"android"},{"run_id":"21236250461","status":"❌ 실패","status_class":"failure","timestamp":"2026-01-22 13:53:22","platform":"android"},{"run_id":"21236186305","status":"❌ 실패","status_class":"failure","timestamp":"2026-01-22 13:36:57","platform":"android"},{"run_id":"21236002274","status":"❌ 실패","status_class":"failure","timestamp":"2026-01-22 13:28:56","platform":"android"},{"run_id":"21235999987","status":"❌ 실패","status_class":"failure","timestamp":"2026-01-22 13:28:50","platform":"android"},{"run_id":"21235762100","status":"❌ 실패","status_class":"failure","timestamp":"2026-01-22 13:16:24","platform":"android"},{"run_id":"21235759851","status":"❌ 실패","status_class":"failure","timestamp":"2026-01-22 13:16:14","platform":"android"},{"run_id":"21235077319","status":"❌ 실패","status_class":"failure","timestamp":"2026-01-22 13:08:14","platform":"android"},{"run_id":"21234122553","status":"❌ 실패","status_class":"failure","timestamp":"2026-01-22 11:57:12","platform":"android"},{"run_id":"21234121195","status":"❌ 실패","status_class":"failure","timestamp":"2026-01-22 11:58:06","platform":"android"},{"run_id":"21234091209","status":"❌ 실패","status_class":"failure","timestamp":"2026-01-22 11:46:30","platform":"android"},{"run_id":"21234078890","status":"❌ 실패","status_class":"failure","timestamp":"2026-01-22 11:45:50","platform":"android"}];
57+
const stagingHistory = [{"run_id":"21350089288-ios","status":"✅ 성공","status_class":"success","timestamp":"2026-01-26 16:50:32","platform":"ios"},{"run_id":"21349493647-ios","status":"❌ 실패","status_class":"failure","timestamp":"2026-01-26 16:23:28","platform":"ios"},{"run_id":"21349447163-android","status":"❌ 실패","status_class":"failure","timestamp":"2026-01-26 16:22:29","platform":"android"},{"run_id":"21349349274-android","status":"✅ 성공","status_class":"success","timestamp":"2026-01-26 16:21:12","platform":"android"},{"run_id":"21349347409-ios","status":"✅ 성공","status_class":"success","timestamp":"2026-01-26 16:16:30","platform":"ios"},{"run_id":"21349347409-android","status":"✅ 성공","status_class":"success","timestamp":"2026-01-26 16:18:46","platform":"android"},{"run_id":"21349227630-android","status":"✅ 성공","status_class":"success","timestamp":"2026-01-26 16:11:45","platform":"android"},{"run_id":"21349106806-android","status":"❌ 실패","status_class":"failure","timestamp":"2026-01-26 16:09:05","platform":"android"},{"run_id":"21349104503-ios","status":"✅ 성공","status_class":"success","timestamp":"2026-01-26 16:07:27","platform":"ios"},{"run_id":"21349104503-android","status":"✅ 성공","status_class":"success","timestamp":"2026-01-26 16:06:31","platform":"android"},{"run_id":"21349046528-android","status":"❌ 실패","status_class":"failure","timestamp":"2026-01-26 16:03:00","platform":"android"},{"run_id":"21348949966-android","status":"❌ 실패","status_class":"failure","timestamp":"2026-01-26 15:57:52","platform":"android"},{"run_id":"21348785037","status":"❌ 실패","status_class":"failure","timestamp":"2026-01-26 15:49:23","platform":"android"},{"run_id":"21348753276","status":"✅ 성공","status_class":"success","timestamp":"2026-01-26 15:47:18","platform":"android"},{"run_id":"21329397942","status":"❌ 실패","status_class":"failure","timestamp":"2026-01-25 23:07:26","platform":"android"},{"run_id":"21279731003","status":"✅ 성공","status_class":"success","timestamp":"2026-01-23 17:32:02","platform":"android"},{"run_id":"21240824573","status":"✅ 성공","status_class":"success","timestamp":"2026-01-22 17:09:15","platform":"android"},{"run_id":"21240728460","status":"✅ 성공","status_class":"success","timestamp":"2026-01-22 17:05:14","platform":"android"},{"run_id":"21237795149","status":"✅ 성공","status_class":"success","timestamp":"2026-01-22 14:57:17","platform":"android"},{"run_id":"21237696679","status":"✅ 성공","status_class":"success","timestamp":"2026-01-22 14:52:30","platform":"android"},{"run_id":"21237534475","status":"✅ 성공","status_class":"success","timestamp":"2026-01-22 14:44:29","platform":"android"},{"run_id":"21236250461","status":"❌ 실패","status_class":"failure","timestamp":"2026-01-22 13:53:22","platform":"android"},{"run_id":"21236186305","status":"❌ 실패","status_class":"failure","timestamp":"2026-01-22 13:36:57","platform":"android"},{"run_id":"21236002274","status":"❌ 실패","status_class":"failure","timestamp":"2026-01-22 13:28:56","platform":"android"},{"run_id":"21235999987","status":"❌ 실패","status_class":"failure","timestamp":"2026-01-22 13:28:50","platform":"android"},{"run_id":"21235762100","status":"❌ 실패","status_class":"failure","timestamp":"2026-01-22 13:16:24","platform":"android"},{"run_id":"21235759851","status":"❌ 실패","status_class":"failure","timestamp":"2026-01-22 13:16:14","platform":"android"},{"run_id":"21235077319","status":"❌ 실패","status_class":"failure","timestamp":"2026-01-22 13:08:14","platform":"android"},{"run_id":"21234122553","status":"❌ 실패","status_class":"failure","timestamp":"2026-01-22 11:57:12","platform":"android"},{"run_id":"21234121195","status":"❌ 실패","status_class":"failure","timestamp":"2026-01-22 11:58:06","platform":"android"},{"run_id":"21234091209","status":"❌ 실패","status_class":"failure","timestamp":"2026-01-22 11:46:30","platform":"android"},{"run_id":"21234078890","status":"❌ 실패","status_class":"failure","timestamp":"2026-01-22 11:45:50","platform":"android"}];
5858
function renderStats(h, id) {
5959
var t=h.length, s=h.filter(x=>x.status_class==='success').length, f=t-s, r=t>0?Math.round((s/t)*100):0;
6060
document.getElementById(id).innerHTML = '<div class="stat-card"><div class="number">'+t+'</div><div class="label">전체</div></div><div class="stat-card success"><div class="number">'+s+'</div><div class="label">성공</div></div><div class="stat-card failure"><div class="number">'+f+'</div><div class="label">실패</div></div><div class="stat-card"><div class="number">'+r+'%</div><div class="label">성공률</div></div>';
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
staging
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
app-staging
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
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>APP 테스트 결과 - 21350089288 (ios)</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+
.platform-badge { display: inline-block; padding: 3px 10px; border-radius: 12px; font-size: 12px; font-weight: 500; margin-left: 10px; }
21+
.platform-badge.android { background: #a4c639; color: white; }
22+
.platform-badge.ios { background: #007aff; color: white; }
23+
.section { background: white; padding: 20px; border-radius: 10px; margin-bottom: 20px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
24+
.section h2 { font-size: 18px; margin-bottom: 15px; padding-bottom: 10px; border-bottom: 1px solid #eee; }
25+
.log-content { background: #1e1e1e; color: #d4d4d4; padding: 15px; border-radius: 5px; font-family: monospace; font-size: 13px; overflow-x: auto; white-space: pre-wrap; max-height: 500px; overflow-y: auto; }
26+
.back-link { display: inline-block; margin-bottom: 20px; color: #007bff; text-decoration: none; }
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; }
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 img { max-width: 300px; border: 1px solid #ddd; border-radius: 4px; margin-top: 10px; }
43+
</style>
44+
</head>
45+
<body>
46+
<div class="container">
47+
<a href="../../app-index.html" class="back-link">← 전체 히스토리로 돌아가기</a>
48+
<div class="header">
49+
<h1>📱 APP 테스트 결과 <span class="status-badge success">✅ 성공</span><span class="platform-badge ios">iOS</span></h1>
50+
<div class="meta">
51+
<div class="meta-item"><label>Run ID</label><span>21350089288</span></div>
52+
<div class="meta-item"><label>환경</label><span>스테이징</span></div>
53+
<div class="meta-item"><label>플랫폼</label><span>iOS</span></div>
54+
<div class="meta-item"><label>Branch</label><span>staging</span></div>
55+
<div class="meta-item"><label>Commit</label><span>9a9e157</span></div>
56+
<div class="meta-item"><label>실행 시간</label><span>2026-01-26 16:50:32</span></div>
57+
</div>
58+
</div>
59+
<div class="section">
60+
<h2>🧪 테스트별 결과</h2>
61+
<div id="test-summary" style="display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:10px;margin-bottom:15px;"></div>
62+
<div class="test-results" id="test-results"><p style="padding:20px;color:#666;">로딩중...</p></div>
63+
</div>
64+
<div class="section">
65+
<h2>📋 테스트 로그</h2>
66+
<pre class="log-content" id="log-content">로딩중...</pre>
67+
</div>
68+
<div class="section">
69+
<h2>📸 스크린샷</h2>
70+
<div class="screenshots" id="screenshots"></div>
71+
</div>
72+
</div>
73+
<script>
74+
fetch('test-results.json').then(r => r.json()).then(results => {
75+
const container = document.getElementById('test-results');
76+
const summary = document.getElementById('test-summary');
77+
if (!results || results.length === 0) { container.innerHTML = '<p style="padding:20px;">결과 없음</p>'; return; }
78+
var total = results.length, success = results.filter(r => r.status === 'success').length;
79+
var failure = total - success, rate = total > 0 ? Math.round((success/total)*100) : 0;
80+
var totalSec = results.reduce((s,r) => s + (r.duration||0), 0);
81+
var h = Math.floor(totalSec/3600), m = Math.floor((totalSec%3600)/60), s = Math.floor(totalSec%60);
82+
var dur = (h>0?h+'시간 ':'') + (m>0?m+'분 ':'') + s+'초';
83+
summary.innerHTML = '<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><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><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><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><div style="padding:15px;border-radius:8px;text-align:center;background:#f3e5f5;"><div style="font-size:20px;font-weight:bold;color:#7b1fa2;">'+dur+'</div><div style="font-size:12px;color:#666;">수행시간</div></div>';
84+
container.innerHTML = results.map(r => {
85+
var icon = r.status==='success'?'✅':'❌';
86+
var msg = r.message?'<div class="test-message">'+r.message+'</div>':'';
87+
var trace = r.traceback?'<div class="test-traceback">'+r.traceback.replace(/</g,'&lt;')+'</div>':'';
88+
var shot = r.screenshot?'<div class="test-screenshot"><a href="'+r.screenshot+'" target="_blank"><img src="'+r.screenshot+'"></a></div>':'';
89+
return '<div class="test-item '+r.status+'"><span class="test-icon">'+icon+'</span><div class="test-info"><div class="test-name">'+r.name+'</div>'+msg+trace+shot+'</div><span class="test-duration">'+r.duration+'s</span></div>';
90+
}).join('');
91+
}).catch(() => { document.getElementById('test-results').innerHTML = '<p style="padding:20px;">결과를 불러올 수 없습니다.</p>'; });
92+
fetch('test-output.log').then(r => r.text()).then(t => { document.getElementById('log-content').textContent = t || '로그 없음'; }).catch(() => { document.getElementById('log-content').textContent = '로그를 불러올 수 없습니다.'; });
93+
const pngs = [];
94+
const sc = document.getElementById('screenshots');
95+
if (pngs.length === 0) { sc.innerHTML = '<p style="color:#666;">스크린샷이 없습니다.</p>'; }
96+
else { pngs.forEach(p => { sc.innerHTML += '<div class="screenshot"><a href="'+p+'" target="_blank"><img src="'+p+'"></a><p>'+p+'</p></div>'; }); }
97+
</script>
98+
</body>
99+
</html>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ios

0 commit comments

Comments
 (0)