2348 lines
78 KiB
Plaintext
2348 lines
78 KiB
Plaintext
$ npx vitest run tests/App.test.tsx tests/neural-release.test.ts
|
||
|
||
RUN v5.0.4 /home/hermes/worktrees/find-word-v0.2.3
|
||
|
||
❯ tests/neural-release.test.ts (4 tests | 1 failed) 54ms
|
||
× README는 현재 리뷰 증거 경로와 정확한 라운드 보너스를 안내한다 44ms
|
||
❯ tests/App.test.tsx (23 tests | 6 failed) 6299ms
|
||
× 오디오 started=false 중 종료는 즉시 정지하고 결과를 거쳐 홈으로 간다 227ms
|
||
× 오디오 started=true 중 종료는 즉시 정지하고 결과를 거쳐 홈으로 간다 208ms
|
||
× 5단계 완료는 6단계 대신 같은 단계의 새 세 문항을 시작한다 601ms
|
||
× 세 문항 라운드에서 가능한 연속 정답 보너스 상한을 설명한다 100ms
|
||
× 현재 문항 진행률은 1/3→2/3→3/3이고 1단계 만점은 330점이다 221ms
|
||
× 무응답 종료는 정답률 대신 미응답 상태와 단계별 미진행을 보여 준다 215ms
|
||
|
||
⎯⎯⎯⎯⎯⎯⎯ Failed Tests 7 ⎯⎯⎯⎯⎯⎯⎯
|
||
|
||
FAIL tests/App.test.tsx > 오디오 started=false 중 종료는 즉시 정지하고 결과를 거쳐 홈으로 간다
|
||
FAIL tests/App.test.tsx > 오디오 started=true 중 종료는 즉시 정지하고 결과를 거쳐 홈으로 간다
|
||
TestingLibraryElementError: Unable to find an accessible element with the role "heading" and name "문제 풀이를 중간에 종료했어요."
|
||
|
||
Here are the accessible roles:
|
||
|
||
link:
|
||
|
||
Name "본문으로 건너뛰기":
|
||
[36m<a[39m
|
||
[33mclass[39m=[32m"skip-link"[39m
|
||
[33mhref[39m=[32m"#main"[39m
|
||
[36m/>[39m
|
||
|
||
Name "환경음 출처·라이선스":
|
||
[36m<a[39m
|
||
[33mhref[39m=[32m"/AMBIENCE_NOTICES.md"[39m
|
||
[36m/>[39m
|
||
|
||
--------------------------------------------------
|
||
banner:
|
||
|
||
Name "":
|
||
[36m<header[39m
|
||
[33mclass[39m=[32m"header wrap"[39m
|
||
[36m/>[39m
|
||
|
||
--------------------------------------------------
|
||
heading:
|
||
|
||
Name "단어를 맞춰라":
|
||
[36m<h1 />[39m
|
||
|
||
Name "문제 풀이를 종료했어요.":
|
||
[36m<h2[39m
|
||
[33mtabindex[39m=[32m"-1"[39m
|
||
[36m/>[39m
|
||
|
||
--------------------------------------------------
|
||
main:
|
||
|
||
Name "":
|
||
[36m<main[39m
|
||
[33mclass[39m=[32m"wrap"[39m
|
||
[33mid[39m=[32m"main"[39m
|
||
[33mtabindex[39m=[32m"-1"[39m
|
||
[36m/>[39m
|
||
|
||
--------------------------------------------------
|
||
paragraph:
|
||
|
||
Name "":
|
||
[36m<p[39m
|
||
[33mclass[39m=[32m"muted"[39m
|
||
[36m/>[39m
|
||
|
||
Name "":
|
||
[36m<p />[39m
|
||
|
||
Name "":
|
||
[36m<p[39m
|
||
[33mclass[39m=[32m"muted"[39m
|
||
[36m/>[39m
|
||
|
||
Name "":
|
||
[36m<p />[39m
|
||
|
||
Name "":
|
||
[36m<p />[39m
|
||
|
||
--------------------------------------------------
|
||
strong:
|
||
|
||
Name "":
|
||
[36m<strong />[39m
|
||
|
||
Name "":
|
||
[36m<strong />[39m
|
||
|
||
Name "":
|
||
[36m<strong />[39m
|
||
|
||
--------------------------------------------------
|
||
table:
|
||
|
||
Name "난이도별 결과":
|
||
[36m<table[39m
|
||
[33maria-label[39m=[32m"난이도별 결과"[39m
|
||
[36m/>[39m
|
||
|
||
--------------------------------------------------
|
||
rowgroup:
|
||
|
||
Name "":
|
||
[36m<thead />[39m
|
||
|
||
Name "":
|
||
[36m<tbody />[39m
|
||
|
||
--------------------------------------------------
|
||
row:
|
||
|
||
Name "난이도 SNR 맞힌 문제":
|
||
[36m<tr />[39m
|
||
|
||
Name "1단계 SNR +6 dB 0 / 0":
|
||
[36m<tr />[39m
|
||
|
||
Name "2단계 SNR +3 dB 0 / 0":
|
||
[36m<tr />[39m
|
||
|
||
Name "3단계 SNR 0 dB 0 / 0":
|
||
[36m<tr />[39m
|
||
|
||
Name "4단계 SNR -3 dB 0 / 0":
|
||
[36m<tr />[39m
|
||
|
||
Name "5단계 SNR -6 dB 0 / 0":
|
||
[36m<tr />[39m
|
||
|
||
--------------------------------------------------
|
||
columnheader:
|
||
|
||
Name "난이도":
|
||
[36m<th[39m
|
||
[33mscope[39m=[32m"col"[39m
|
||
[36m/>[39m
|
||
|
||
Name "SNR":
|
||
[36m<th[39m
|
||
[33mscope[39m=[32m"col"[39m
|
||
[36m/>[39m
|
||
|
||
Name "맞힌 문제":
|
||
[36m<th[39m
|
||
[33mscope[39m=[32m"col"[39m
|
||
[36m/>[39m
|
||
|
||
--------------------------------------------------
|
||
rowheader:
|
||
|
||
Name "1단계":
|
||
[36m<th[39m
|
||
[33mscope[39m=[32m"row"[39m
|
||
[36m/>[39m
|
||
|
||
Name "2단계":
|
||
[36m<th[39m
|
||
[33mscope[39m=[32m"row"[39m
|
||
[36m/>[39m
|
||
|
||
Name "3단계":
|
||
[36m<th[39m
|
||
[33mscope[39m=[32m"row"[39m
|
||
[36m/>[39m
|
||
|
||
Name "4단계":
|
||
[36m<th[39m
|
||
[33mscope[39m=[32m"row"[39m
|
||
[36m/>[39m
|
||
|
||
Name "5단계":
|
||
[36m<th[39m
|
||
[33mscope[39m=[32m"row"[39m
|
||
[36m/>[39m
|
||
|
||
--------------------------------------------------
|
||
cell:
|
||
|
||
Name "SNR +6 dB":
|
||
[36m<td />[39m
|
||
|
||
Name "0 / 0":
|
||
[36m<td />[39m
|
||
|
||
Name "SNR +3 dB":
|
||
[36m<td />[39m
|
||
|
||
Name "0 / 0":
|
||
[36m<td />[39m
|
||
|
||
Name "SNR 0 dB":
|
||
[36m<td />[39m
|
||
|
||
Name "0 / 0":
|
||
[36m<td />[39m
|
||
|
||
Name "SNR -3 dB":
|
||
[36m<td />[39m
|
||
|
||
Name "0 / 0":
|
||
[36m<td />[39m
|
||
|
||
Name "SNR -6 dB":
|
||
[36m<td />[39m
|
||
|
||
Name "0 / 0":
|
||
[36m<td />[39m
|
||
|
||
--------------------------------------------------
|
||
button:
|
||
|
||
Name "처음 화면으로":
|
||
[36m<button[39m
|
||
[33mclass[39m=[32m"secondary"[39m
|
||
[36m/>[39m
|
||
|
||
--------------------------------------------------
|
||
slider:
|
||
|
||
Name "전체 음량":
|
||
[36m<input[39m
|
||
[33mid[39m=[32m"volume"[39m
|
||
[33mmax[39m=[32m"100"[39m
|
||
[33mmin[39m=[32m"0"[39m
|
||
[33mtype[39m=[32m"range"[39m
|
||
[33mvalue[39m=[32m"35"[39m
|
||
[36m/>[39m
|
||
|
||
--------------------------------------------------
|
||
status:
|
||
|
||
Name "":
|
||
[36m<output[39m
|
||
[33mfor[39m=[32m"volume"[39m
|
||
[36m/>[39m
|
||
|
||
--------------------------------------------------
|
||
contentinfo:
|
||
|
||
Name "":
|
||
[36m<footer[39m
|
||
[33mclass[39m=[32m"footer wrap"[39m
|
||
[36m/>[39m
|
||
|
||
--------------------------------------------------
|
||
|
||
Ignored nodes: comments, script, style
|
||
[36m<body>[39m
|
||
[36m<div>[39m
|
||
[36m<a[39m
|
||
[33mclass[39m=[32m"skip-link"[39m
|
||
[33mhref[39m=[32m"#main"[39m
|
||
[36m>[39m
|
||
[0m본문으로 건너뛰기[0m
|
||
[36m</a>[39m
|
||
[36m<header[39m
|
||
[33mclass[39m=[32m"header wrap"[39m
|
||
[36m>[39m
|
||
[36m<div[39m
|
||
[33mclass[39m=[32m"brand"[39m
|
||
[36m>[39m
|
||
[36m<span[39m
|
||
[33maria-hidden[39m=[32m"true"[39m
|
||
[33mclass[39m=[32m"brand-mark"[39m
|
||
[36m>[39m
|
||
[36m<i />[39m
|
||
[36m<i />[39m
|
||
[36m<i />[39m
|
||
[36m<i />[39m
|
||
[36m</span>[39m
|
||
[36m<h1>[39m
|
||
[0m단어를 맞춰라[0m
|
||
[36m</h1>[39m
|
||
[36m<span[39m
|
||
[33mclass[39m=[32m"version"[39m
|
||
[36m>[39m
|
||
[0mv0.2.3[0m
|
||
[36m</span>[39m
|
||
[36m</div>[39m
|
||
[36m<div[39m
|
||
[33mclass[39m=[32m"header-actions"[39m
|
||
[36m>[39m
|
||
[36m<span[39m
|
||
[33mclass[39m=[32m"little-dot"[39m
|
||
[36m/>[39m
|
||
[0m소리에 집중하는 시간[0m
|
||
[36m</div>[39m
|
||
[36m</header>[39m
|
||
[36m<main[39m
|
||
[33mclass[39m=[32m"wrap"[39m
|
||
[33mid[39m=[32m"main"[39m
|
||
[33mtabindex[39m=[32m"-1"[39m
|
||
[36m>[39m
|
||
[36m<section[39m
|
||
[33mclass[39m=[32m"results-panel panel"[39m
|
||
[36m>[39m
|
||
[36m<span[39m
|
||
[33mclass[39m=[32m"eyebrow"[39m
|
||
[36m>[39m
|
||
[0m지금까지의 소리 탐험[0m
|
||
[36m</span>[39m
|
||
[36m<div[39m
|
||
[33mclass[39m=[32m"result-mascot"[39m
|
||
[36m>[39m
|
||
[36m<div[39m
|
||
[33maria-hidden[39m=[32m"true"[39m
|
||
[33mclass[39m=[32m"mascot small"[39m
|
||
[36m>[39m
|
||
[36m<span[39m
|
||
[33mclass[39m=[32m"ear left"[39m
|
||
[36m/>[39m
|
||
[36m<span[39m
|
||
[33mclass[39m=[32m"ear right"[39m
|
||
[36m/>[39m
|
||
[36m<span[39m
|
||
[33mclass[39m=[32m"eye left"[39m
|
||
[36m/>[39m
|
||
[36m<span[39m
|
||
[33mclass[39m=[32m"eye right"[39m
|
||
[36m/>[39m
|
||
[36m<span[39m
|
||
[33mclass[39m=[32m"smile"[39m
|
||
[36m/>[39m
|
||
[36m<b>[39m
|
||
[0mS[0m
|
||
[36m</b>[39m
|
||
[36m</div>[39m
|
||
[36m</div>[39m
|
||
[36m<h2[39m
|
||
[33mtabindex[39m=[32m"-1"[39m
|
||
[36m>[39m
|
||
[0m문제 풀이를 종료했어요.[0m
|
||
[36m</h2>[39m
|
||
[36m<p[39m
|
||
[33mclass[39m=[32m"muted"[39m
|
||
[36m>[39m
|
||
[0m작은 소리에 집중한 당신, 다음 탐험에서도 만나요.[0m
|
||
[36m</p>[39m
|
||
[36m<p>[39m
|
||
[0m응답 [0m
|
||
[0m0[0m
|
||
[0m문항 · 정답 [0m
|
||
[0m0[0m
|
||
[0m문항[0m
|
||
[36m</p>[39m
|
||
[36m<div[39m
|
||
[33mclass[39m=[32m"stats"[39m
|
||
[36m>[39m
|
||
[36m<div>[39m
|
||
[36m<strong>[39m
|
||
[0m0[0m
|
||
[36m</strong>[39m
|
||
[36m<span>[39m
|
||
[0m총 점수[0m
|
||
[36m</span>[39m
|
||
[36m</div>[39m
|
||
[36m<div>[39m
|
||
[36m<strong>[39m
|
||
[0m0[0m
|
||
[0m%[0m
|
||
[36m</strong>[39m
|
||
[36m<span>[39m
|
||
[0m정답률 · [0m
|
||
[0m0[0m
|
||
[0m/[0m
|
||
[0m0[0m
|
||
[36m</span>[39m
|
||
[36m</div>[39m
|
||
[36m<div>[39m
|
||
[36m<strong>[39m
|
||
[0m0[0m
|
||
[36m<small>[39m
|
||
[0m회[0m
|
||
[36m</small>[39m
|
||
[36m</strong>[39m
|
||
[36m<span>[39m
|
||
[0m최고 연속 정답[0m
|
||
[36m</span>[39m
|
||
[36m</div>[39m
|
||
[36m</div>[39m
|
||
[36m<table[39m
|
||
[33maria-label[39m=[32m"난이도별 결과"[39m
|
||
[36m>[39m
|
||
[36m<thead>[39m
|
||
[36m<tr>[39m
|
||
[36m<th[39m
|
||
[33mscope[39m=[32m"col"[39m
|
||
[36m>[39m
|
||
[0m난이도[0m
|
||
[36m</th>[39m
|
||
[36m<th[39m
|
||
[33mscope[39m=[32m"col"[39m
|
||
[36m>[39m
|
||
[0mSNR[0m
|
||
[36m</th>[39m
|
||
[36m<th[39m
|
||
[33mscope[39m=[32m"col"[39m
|
||
[36m>[39m
|
||
[0m맞힌 문제[0m
|
||
[36m</th>[39m
|
||
[36m</tr>[39m
|
||
[36m</thead>[39m
|
||
[36m<tbody>[39m
|
||
[36m<tr>[39m
|
||
[36m<th[39m
|
||
[33mscope[39m=[32m"row"[39m
|
||
[36m>[39m
|
||
[0m1[0m
|
||
[0m단계[0m
|
||
[36m</th>[39m
|
||
[36m<td>[39m
|
||
[0mSNR +6 dB[0m
|
||
[36m</td>[39m
|
||
[36m<td>[39m
|
||
[0m0[0m
|
||
[0m / [0m
|
||
[0m0[0m
|
||
[36m</td>[39m
|
||
[36m</tr>[39m
|
||
[36m<tr>[39m
|
||
[36m<th[39m
|
||
[33mscope[39m=[32m"row"[39m
|
||
[36m>[39m
|
||
[0m2[0m
|
||
[0m단계[0m
|
||
[36m</th>[39m
|
||
[36m<td>[39m
|
||
[0mSNR +3 dB[0m
|
||
[36m</td>[39m
|
||
[36m<td>[39m
|
||
[0m0[0m
|
||
[0m / [0m
|
||
[0m0[0m
|
||
[36m</td>[39m
|
||
[36m</tr>[39m
|
||
[36m<tr>[39m
|
||
[36m<th[39m
|
||
[33mscope[39m=[32m"row"[39m
|
||
[36m>[39m
|
||
[0m3[0m
|
||
[0m단계[0m
|
||
[36m</th>[39m
|
||
[36m<td>[39m
|
||
[0mSNR 0 dB[0m
|
||
[36m</td>[39m
|
||
[36m<td>[39m
|
||
[0m0[0m
|
||
[0m / [0m
|
||
[0m0[0m
|
||
[36m</td>[39m
|
||
[36m</tr>[39m
|
||
[36m<tr>[39m
|
||
[36m<th[39m
|
||
[33mscope[39m=[32m"row"[39m
|
||
[36m>[39m
|
||
[0m4[0m
|
||
[0m단계[0m
|
||
[36m</th>[39m
|
||
[36m<td>[39m
|
||
[0mSNR -3 dB[0m
|
||
[36m</td>[39m
|
||
[36m<td>[39m
|
||
[0m0[0m
|
||
[0m / [0m
|
||
[0m0[0m
|
||
[36m</td>[39m
|
||
[36m</tr>[39m
|
||
[36m<tr>[39m
|
||
[36m<th[39m
|
||
[33mscope[39m=[32m"row"[39m
|
||
[36m>[39m
|
||
[0m5[0m
|
||
[0m단계[0m
|
||
[36m</th>[39m
|
||
[36m<td>[39m
|
||
[0mSNR -6 dB[0m
|
||
[36m</td>[39m
|
||
[36m<td>[39m
|
||
[0m0[0m
|
||
[0m / [0m
|
||
[0m0[0m
|
||
[36m</td>[39m
|
||
[36m</tr>[39m
|
||
[36m</tbody>[39m
|
||
[36m</table>[39m
|
||
[36m<p[39m
|
||
[33mclass[39m=[32m"muted"[39m
|
||
[36m>[39m
|
||
[0m단계 × 100점 + 연속 정답 보너스 (라운드 내 최대[0m
|
||
[0m [0m
|
||
[0m20[0m
|
||
[0m점)[0m
|
||
[36m</p>[39m
|
||
[36m<button[39m
|
||
[33mclass[39m=[32m"secondary"[39m
|
||
[36m>[39m
|
||
[0m처음 화면으로[0m
|
||
[36m</button>[39m
|
||
[36m</section>[39m
|
||
[36m<div[39m
|
||
[33mclass[39m=[32m"volume-row"[39m
|
||
[36m>[39m
|
||
[36m<label[39m
|
||
[33mfor[39m=[32m"volume"[39m
|
||
[36m>[39m
|
||
[36m<span[39m
|
||
[33maria-hidden[39m=[32m"true"[39m
|
||
[36m>[39m
|
||
[0m◖))[0m
|
||
[36m</span>[39m
|
||
[0m 전체 음량[0m
|
||
[36m</label>[39m
|
||
[36m<input[39m
|
||
[33mid[39m=[32m"volume"[39m
|
||
[33mmax[39m=[32m"100"[39m
|
||
[33mmin[39m=[32m"0"[39m
|
||
[33mtype[39m=[32m"range"[39m
|
||
[33mvalue[39m=[32m"35"[39m
|
||
[36m/>[39m
|
||
[36m<output[39m
|
||
[33mfor[39m=[32m"volume"[39m
|
||
[36m>[39m
|
||
[0m35[0m
|
||
[0m%[0m
|
||
[36m</output>[39m
|
||
[36m</div>[39m
|
||
[36m</main>[39m
|
||
[36m<footer[39m
|
||
[33mclass[39m=[32m"footer wrap"[39m
|
||
[36m>[39m
|
||
[36m<p>[39m
|
||
[0mDesigned by OZ at Heat-T Medical Inc.[0m
|
||
[36m</p>[39m
|
||
[36m<p>[39m
|
||
[0m청각적 주의·식별 게임 · 의료적 진단이나 치료를 제공하지 않습니다.[0m
|
||
[36m</p>[39m
|
||
[36m<span>[39m
|
||
[0m개인정보 수집 없이, 오직 플레이만.[0m
|
||
[36m</span>[39m
|
||
[36m<a[39m
|
||
[33mhref[39m=[32m"/AMBIENCE_NOTICES.md"[39m
|
||
[36m>[39m
|
||
[0m환경음 출처·라이선스[0m
|
||
[36m</a>[39m
|
||
[36m</footer>[39m
|
||
[36m</div>[39m
|
||
[36m</body>[39m
|
||
❯ Object.getElementError node_modules/@testing-library/dom/dist/config.js:37:19
|
||
❯ node_modules/@testing-library/dom/dist/query-helpers.js:76:38
|
||
❯ node_modules/@testing-library/dom/dist/query-helpers.js:52:17
|
||
❯ node_modules/@testing-library/dom/dist/query-helpers.js:95:19
|
||
❯ tests/App.test.tsx:415:14
|
||
413| expect(f.audio.stop).toHaveBeenCalledOnce();
|
||
414| expect(
|
||
415| screen.getByRole("heading", { name: "문제 풀이를 중간에 종료했어요." }),
|
||
| ^
|
||
416| ).toHaveFocus();
|
||
417| expect(screen.getByText("응답 0문항 · 정답 0문항")).toBeInTheDocument();
|
||
|
||
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/8]⎯
|
||
|
||
FAIL tests/App.test.tsx > 5단계 완료는 6단계 대신 같은 단계의 새 세 문항을 시작한다
|
||
Error: expect(element).toHaveAttribute("value", "1") // element.getAttribute("value") === "1"
|
||
|
||
Expected the element to have attribute:
|
||
value="1"
|
||
Received:
|
||
value="0"
|
||
❯ tests/App.test.tsx:477:43
|
||
475| );
|
||
476| expect(screen.getByRole("progressbar")).toHaveAttribute("max", "3");
|
||
477| expect(screen.getByRole("progressbar")).toHaveAttribute("value", "1"…
|
||
| ^
|
||
478| await f.finish();
|
||
479| });
|
||
|
||
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/8]⎯
|
||
|
||
FAIL tests/App.test.tsx > 세 문항 라운드에서 가능한 연속 정답 보너스 상한을 설명한다
|
||
TestingLibraryElementError: Unable to find an element with the text: 정답마다 단계 × 100점 + 연속 정답 보너스 (문항별 최대 20점, 라운드 합계 최대 30점). This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.
|
||
|
||
Ignored nodes: comments, script, style
|
||
[36m<body>[39m
|
||
[36m<div>[39m
|
||
[36m<a[39m
|
||
[33mclass[39m=[32m"skip-link"[39m
|
||
[33mhref[39m=[32m"#main"[39m
|
||
[36m>[39m
|
||
[0m본문으로 건너뛰기[0m
|
||
[36m</a>[39m
|
||
[36m<header[39m
|
||
[33mclass[39m=[32m"header wrap"[39m
|
||
[36m>[39m
|
||
[36m<div[39m
|
||
[33mclass[39m=[32m"brand"[39m
|
||
[36m>[39m
|
||
[36m<span[39m
|
||
[33maria-hidden[39m=[32m"true"[39m
|
||
[33mclass[39m=[32m"brand-mark"[39m
|
||
[36m>[39m
|
||
[36m<i />[39m
|
||
[36m<i />[39m
|
||
[36m<i />[39m
|
||
[36m<i />[39m
|
||
[36m</span>[39m
|
||
[36m<h1>[39m
|
||
[0m단어를 맞춰라[0m
|
||
[36m</h1>[39m
|
||
[36m<span[39m
|
||
[33mclass[39m=[32m"version"[39m
|
||
[36m>[39m
|
||
[0mv0.2.3[0m
|
||
[36m</span>[39m
|
||
[36m</div>[39m
|
||
[36m<div[39m
|
||
[33mclass[39m=[32m"header-actions"[39m
|
||
[36m>[39m
|
||
[36m<span[39m
|
||
[33mclass[39m=[32m"little-dot"[39m
|
||
[36m/>[39m
|
||
[0m소리에 집중하는 시간[0m
|
||
[36m</div>[39m
|
||
[36m</header>[39m
|
||
[36m<main[39m
|
||
[33mclass[39m=[32m"wrap"[39m
|
||
[33mid[39m=[32m"main"[39m
|
||
[33mtabindex[39m=[32m"-1"[39m
|
||
[36m>[39m
|
||
[36m<section[39m
|
||
[33mclass[39m=[32m"results-panel panel"[39m
|
||
[36m>[39m
|
||
[36m<span[39m
|
||
[33mclass[39m=[32m"eyebrow"[39m
|
||
[36m>[39m
|
||
[0m지금까지의 소리 탐험[0m
|
||
[36m</span>[39m
|
||
[36m<div[39m
|
||
[33mclass[39m=[32m"result-mascot"[39m
|
||
[36m>[39m
|
||
[36m<div[39m
|
||
[33maria-hidden[39m=[32m"true"[39m
|
||
[33mclass[39m=[32m"mascot small"[39m
|
||
[36m>[39m
|
||
[36m<span[39m
|
||
[33mclass[39m=[32m"ear left"[39m
|
||
[36m/>[39m
|
||
[36m<span[39m
|
||
[33mclass[39m=[32m"ear right"[39m
|
||
[36m/>[39m
|
||
[36m<span[39m
|
||
[33mclass[39m=[32m"eye left"[39m
|
||
[36m/>[39m
|
||
[36m<span[39m
|
||
[33mclass[39m=[32m"eye right"[39m
|
||
[36m/>[39m
|
||
[36m<span[39m
|
||
[33mclass[39m=[32m"smile"[39m
|
||
[36m/>[39m
|
||
[36m<b>[39m
|
||
[0mS[0m
|
||
[36m</b>[39m
|
||
[36m</div>[39m
|
||
[36m</div>[39m
|
||
[36m<h2[39m
|
||
[33mtabindex[39m=[32m"-1"[39m
|
||
[36m>[39m
|
||
[0m문제 풀이를 종료했어요.[0m
|
||
[36m</h2>[39m
|
||
[36m<p[39m
|
||
[33mclass[39m=[32m"muted"[39m
|
||
[36m>[39m
|
||
[0m작은 소리에 집중한 당신, 다음 탐험에서도 만나요.[0m
|
||
[36m</p>[39m
|
||
[36m<p>[39m
|
||
[0m응답 [0m
|
||
[0m0[0m
|
||
[0m문항 · 정답 [0m
|
||
[0m0[0m
|
||
[0m문항[0m
|
||
[36m</p>[39m
|
||
[36m<div[39m
|
||
[33mclass[39m=[32m"stats"[39m
|
||
[36m>[39m
|
||
[36m<div>[39m
|
||
[36m<strong>[39m
|
||
[0m0[0m
|
||
[36m</strong>[39m
|
||
[36m<span>[39m
|
||
[0m총 점수[0m
|
||
[36m</span>[39m
|
||
[36m</div>[39m
|
||
[36m<div>[39m
|
||
[36m<strong>[39m
|
||
[0m0[0m
|
||
[0m%[0m
|
||
[36m</strong>[39m
|
||
[36m<span>[39m
|
||
[0m정답률 · [0m
|
||
[0m0[0m
|
||
[0m/[0m
|
||
[0m0[0m
|
||
[36m</span>[39m
|
||
[36m</div>[39m
|
||
[36m<div>[39m
|
||
[36m<strong>[39m
|
||
[0m0[0m
|
||
[36m<small>[39m
|
||
[0m회[0m
|
||
[36m</small>[39m
|
||
[36m</strong>[39m
|
||
[36m<span>[39m
|
||
[0m최고 연속 정답[0m
|
||
[36m</span>[39m
|
||
[36m</div>[39m
|
||
[36m</div>[39m
|
||
[36m<table[39m
|
||
[33maria-label[39m=[32m"난이도별 결과"[39m
|
||
[36m>[39m
|
||
[36m<thead>[39m
|
||
[36m<tr>[39m
|
||
[36m<th[39m
|
||
[33mscope[39m=[32m"col"[39m
|
||
[36m>[39m
|
||
[0m난이도[0m
|
||
[36m</th>[39m
|
||
[36m<th[39m
|
||
[33mscope[39m=[32m"col"[39m
|
||
[36m>[39m
|
||
[0mSNR[0m
|
||
[36m</th>[39m
|
||
[36m<th[39m
|
||
[33mscope[39m=[32m"col"[39m
|
||
[36m>[39m
|
||
[0m맞힌 문제[0m
|
||
[36m</th>[39m
|
||
[36m</tr>[39m
|
||
[36m</thead>[39m
|
||
[36m<tbody>[39m
|
||
[36m<tr>[39m
|
||
[36m<th[39m
|
||
[33mscope[39m=[32m"row"[39m
|
||
[36m>[39m
|
||
[0m1[0m
|
||
[0m단계[0m
|
||
[36m</th>[39m
|
||
[36m<td>[39m
|
||
[0mSNR +6 dB[0m
|
||
[36m</td>[39m
|
||
[36m<td>[39m
|
||
[0m0[0m
|
||
[0m / [0m
|
||
[0m0[0m
|
||
[36m</td>[39m
|
||
[36m</tr>[39m
|
||
[36m<tr>[39m
|
||
[36m<th[39m
|
||
[33mscope[39m=[32m"row"[39m
|
||
[36m>[39m
|
||
[0m2[0m
|
||
[0m단계[0m
|
||
[36m</th>[39m
|
||
[36m<td>[39m
|
||
[0mSNR +3 dB[0m
|
||
[36m</td>[39m
|
||
[36m<td>[39m
|
||
[0m0[0m
|
||
[0m / [0m
|
||
[0m0[0m
|
||
[36m</td>[39m
|
||
[36m</tr>[39m
|
||
[36m<tr>[39m
|
||
[36m<th[39m
|
||
[33mscope[39m=[32m"row"[39m
|
||
[36m>[39m
|
||
[0m3[0m
|
||
[0m단계[0m
|
||
[36m</th>[39m
|
||
[36m<td>[39m
|
||
[0mSNR 0 dB[0m
|
||
[36m</td>[39m
|
||
[36m<td>[39m
|
||
[0m0[0m
|
||
[0m / [0m
|
||
[0m0[0m
|
||
[36m</td>[39m
|
||
[36m</tr>[39m
|
||
[36m<tr>[39m
|
||
[36m<th[39m
|
||
[33mscope[39m=[32m"row"[39m
|
||
[36m>[39m
|
||
[0m4[0m
|
||
[0m단계[0m
|
||
[36m</th>[39m
|
||
[36m<td>[39m
|
||
[0mSNR -3 dB[0m
|
||
[36m</td>[39m
|
||
[36m<td>[39m
|
||
[0m0[0m
|
||
[0m / [0m
|
||
[0m0[0m
|
||
[36m</td>[39m
|
||
[36m</tr>[39m
|
||
[36m<tr>[39m
|
||
[36m<th[39m
|
||
[33mscope[39m=[32m"row"[39m
|
||
[36m>[39m
|
||
[0m5[0m
|
||
[0m단계[0m
|
||
[36m</th>[39m
|
||
[36m<td>[39m
|
||
[0mSNR -6 dB[0m
|
||
[36m</td>[39m
|
||
[36m<td>[39m
|
||
[0m0[0m
|
||
[0m / [0m
|
||
[0m0[0m
|
||
[36m</td>[39m
|
||
[36m</tr>[39m
|
||
[36m</tbody>[39m
|
||
[36m</table>[39m
|
||
[36m<p[39m
|
||
[33mclass[39m=[32m"muted"[39m
|
||
[36m>[39m
|
||
[0m단계 × 100점 + 연속 정답 보너스 (라운드 내 최대[0m
|
||
[0m [0m
|
||
[0m20[0m
|
||
[0m점)[0m
|
||
[36m</p>[39m
|
||
[36m<button[39m
|
||
[33mclass[39m=[32m"secondary"[39m
|
||
[36m>[39m
|
||
[0m처음 화면으로[0m
|
||
[36m</button>[39m
|
||
[36m</section>[39m
|
||
[36m<div[39m
|
||
[33mclass[39m=[32m"volume-row"[39m
|
||
[36m>[39m
|
||
[36m<label[39m
|
||
[33mfor[39m=[32m"volume"[39m
|
||
[36m>[39m
|
||
[36m<span[39m
|
||
[33maria-hidden[39m=[32m"true"[39m
|
||
[36m>[39m
|
||
[0m◖))[0m
|
||
[36m</span>[39m
|
||
[0m 전체 음량[0m
|
||
[36m</label>[39m
|
||
[36m<input[39m
|
||
[33mid[39m=[32m"volume"[39m
|
||
[33mmax[39m=[32m"100"[39m
|
||
[33mmin[39m=[32m"0"[39m
|
||
[33mtype[39m=[32m"range"[39m
|
||
[33mvalue[39m=[32m"35"[39m
|
||
[36m/>[39m
|
||
[36m<output[39m
|
||
[33mfor[39m=[32m"volume"[39m
|
||
[36m>[39m
|
||
[0m35[0m
|
||
[0m%[0m
|
||
[36m</output>[39m
|
||
[36m</div>[39m
|
||
[36m</main>[39m
|
||
[36m<footer[39m
|
||
[33mclass[39m=[32m"footer wrap"[39m
|
||
[36m>[39m
|
||
[36m<p>[39m
|
||
[0mDesigned by OZ at Heat-T Medical Inc.[0m
|
||
[36m</p>[39m
|
||
[36m<p>[39m
|
||
[0m청각적 주의·식별 게임 · 의료적 진단이나 치료를 제공하지 않습니다.[0m
|
||
[36m</p>[39m
|
||
[36m<span>[39m
|
||
[0m개인정보 수집 없이, 오직 플레이만.[0m
|
||
[36m</span>[39m
|
||
[36m<a[39m
|
||
[33mhref[39m=[32m"/AMBIENCE_NOTICES.md"[39m
|
||
[36m>[39m
|
||
[0m환경음 출처·라이선스[0m
|
||
[36m</a>[39m
|
||
[36m</footer>[39m
|
||
[36m</div>[39m
|
||
[36m</body>[39m
|
||
❯ Object.getElementError node_modules/@testing-library/dom/dist/config.js:37:19
|
||
❯ node_modules/@testing-library/dom/dist/query-helpers.js:76:38
|
||
❯ node_modules/@testing-library/dom/dist/query-helpers.js:52:17
|
||
❯ node_modules/@testing-library/dom/dist/query-helpers.js:95:19
|
||
❯ tests/App.test.tsx:507:12
|
||
505| await f.user.click(screen.getByRole("button", { name: "문제 풀이 종료" }));
|
||
506| expect(
|
||
507| screen.getByText("정답마다 단계 × 100점 + 연속 정답 보너스 (문항별 최대 20점, 라운드 합계 최…
|
||
| ^
|
||
508| ).toBeInTheDocument();
|
||
509| await f.finish();
|
||
|
||
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/8]⎯
|
||
|
||
FAIL tests/App.test.tsx > 현재 문항 진행률은 1/3→2/3→3/3이고 1단계 만점은 330점이다
|
||
TestingLibraryElementError: Unable to find an accessible element with the role "progressbar" and name "현재 문항 진행률"
|
||
|
||
Here are the accessible roles:
|
||
|
||
link:
|
||
|
||
Name "본문으로 건너뛰기":
|
||
[36m<a[39m
|
||
[33mclass[39m=[32m"skip-link"[39m
|
||
[33mhref[39m=[32m"#main"[39m
|
||
[36m/>[39m
|
||
|
||
Name "환경음 출처·라이선스":
|
||
[36m<a[39m
|
||
[33mhref[39m=[32m"/AMBIENCE_NOTICES.md"[39m
|
||
[36m/>[39m
|
||
|
||
--------------------------------------------------
|
||
banner:
|
||
|
||
Name "":
|
||
[36m<header[39m
|
||
[33mclass[39m=[32m"header wrap"[39m
|
||
[36m/>[39m
|
||
|
||
--------------------------------------------------
|
||
heading:
|
||
|
||
Name "단어를 맞춰라":
|
||
[36m<h1 />[39m
|
||
|
||
Name "카페":
|
||
[36m<h2 />[39m
|
||
|
||
Name "소리 사이에 집중해 보세요.":
|
||
[36m<h2[39m
|
||
[33mtabindex[39m=[32m"-1"[39m
|
||
[36m/>[39m
|
||
|
||
--------------------------------------------------
|
||
button:
|
||
|
||
Name "문제 풀이 종료":
|
||
[36m<button[39m
|
||
[33mclass[39m=[32m"text-button"[39m
|
||
[36m/>[39m
|
||
|
||
Name "듣는 중…":
|
||
[36m<button[39m
|
||
[33mclass[39m=[32m"secondary"[39m
|
||
[33mdisabled[39m=[32m""[39m
|
||
[36m/>[39m
|
||
|
||
Name "듣기 중단":
|
||
[36m<button[39m
|
||
[33mclass[39m=[32m"text-button"[39m
|
||
[36m/>[39m
|
||
|
||
--------------------------------------------------
|
||
main:
|
||
|
||
Name "":
|
||
[36m<main[39m
|
||
[33mclass[39m=[32m"wrap"[39m
|
||
[33mid[39m=[32m"main"[39m
|
||
[33mtabindex[39m=[32m"-1"[39m
|
||
[36m/>[39m
|
||
|
||
--------------------------------------------------
|
||
region:
|
||
|
||
Name "단어 찾기 게임":
|
||
[36m<section[39m
|
||
[33maria-label[39m=[32m"단어 찾기 게임"[39m
|
||
[33mclass[39m=[32m"game-layout"[39m
|
||
[36m/>[39m
|
||
|
||
--------------------------------------------------
|
||
progressbar:
|
||
|
||
Name "전체 진행률":
|
||
[36m<progress[39m
|
||
[33maria-label[39m=[32m"전체 진행률"[39m
|
||
[33mmax[39m=[32m"3"[39m
|
||
[33mvalue[39m=[32m"0"[39m
|
||
[36m/>[39m
|
||
|
||
--------------------------------------------------
|
||
complementary:
|
||
|
||
Name "":
|
||
[36m<aside[39m
|
||
[33mclass[39m=[32m"environment-panel"[39m
|
||
[36m/>[39m
|
||
|
||
--------------------------------------------------
|
||
paragraph:
|
||
|
||
Name "":
|
||
[36m<p[39m
|
||
[33mclass[39m=[32m"eyebrow"[39m
|
||
[36m/>[39m
|
||
|
||
Name "":
|
||
[36m<p />[39m
|
||
|
||
Name "":
|
||
[36m<p[39m
|
||
[33mclass[39m=[32m"db-note"[39m
|
||
[36m/>[39m
|
||
|
||
Name "":
|
||
[36m<p[39m
|
||
[33mid[39m=[32m"snr-help"[39m
|
||
[36m/>[39m
|
||
|
||
Name "":
|
||
[36m<p />[39m
|
||
|
||
Name "":
|
||
[36m<p />[39m
|
||
|
||
Name "":
|
||
[36m<p />[39m
|
||
|
||
--------------------------------------------------
|
||
slider:
|
||
|
||
Name "목표 음성 SNR":
|
||
[36m<input[39m
|
||
[33maria-describedby[39m=[32m"snr-help"[39m
|
||
[33mid[39m=[32m"snr"[39m
|
||
[33mmax[39m=[32m"12"[39m
|
||
[33mmin[39m=[32m"-12"[39m
|
||
[33mstep[39m=[32m"1"[39m
|
||
[33mtype[39m=[32m"range"[39m
|
||
[33mvalue[39m=[32m"6"[39m
|
||
[36m/>[39m
|
||
|
||
Name "전체 음량":
|
||
[36m<input[39m
|
||
[33mid[39m=[32m"volume"[39m
|
||
[33mmax[39m=[32m"100"[39m
|
||
[33mmin[39m=[32m"0"[39m
|
||
[33mtype[39m=[32m"range"[39m
|
||
[33mvalue[39m=[32m"35"[39m
|
||
[36m/>[39m
|
||
|
||
--------------------------------------------------
|
||
status:
|
||
|
||
Name "":
|
||
[36m<output[39m
|
||
[33mfor[39m=[32m"snr"[39m
|
||
[36m/>[39m
|
||
|
||
Name "":
|
||
[36m<output[39m
|
||
[33mfor[39m=[32m"volume"[39m
|
||
[36m/>[39m
|
||
|
||
Name "":
|
||
[36m<p[39m
|
||
[33mrole[39m=[32m"status"[39m
|
||
[36m/>[39m
|
||
|
||
--------------------------------------------------
|
||
contentinfo:
|
||
|
||
Name "":
|
||
[36m<footer[39m
|
||
[33mclass[39m=[32m"footer wrap"[39m
|
||
[36m/>[39m
|
||
|
||
--------------------------------------------------
|
||
|
||
Ignored nodes: comments, script, style
|
||
[36m<body>[39m
|
||
[36m<div>[39m
|
||
[36m<a[39m
|
||
[33mclass[39m=[32m"skip-link"[39m
|
||
[33mhref[39m=[32m"#main"[39m
|
||
[36m>[39m
|
||
[0m본문으로 건너뛰기[0m
|
||
[36m</a>[39m
|
||
[36m<header[39m
|
||
[33mclass[39m=[32m"header wrap"[39m
|
||
[36m>[39m
|
||
[36m<div[39m
|
||
[33mclass[39m=[32m"brand"[39m
|
||
[36m>[39m
|
||
[36m<span[39m
|
||
[33maria-hidden[39m=[32m"true"[39m
|
||
[33mclass[39m=[32m"brand-mark"[39m
|
||
[36m>[39m
|
||
[36m<i />[39m
|
||
[36m<i />[39m
|
||
[36m<i />[39m
|
||
[36m<i />[39m
|
||
[36m</span>[39m
|
||
[36m<h1>[39m
|
||
[0m단어를 맞춰라[0m
|
||
[36m</h1>[39m
|
||
[36m<span[39m
|
||
[33mclass[39m=[32m"version"[39m
|
||
[36m>[39m
|
||
[0mv0.2.3[0m
|
||
[36m</span>[39m
|
||
[36m</div>[39m
|
||
[36m<div[39m
|
||
[33mclass[39m=[32m"header-actions"[39m
|
||
[36m>[39m
|
||
[36m<button[39m
|
||
[33mclass[39m=[32m"text-button"[39m
|
||
[36m>[39m
|
||
[0m문제 풀이 종료[0m
|
||
[36m</button>[39m
|
||
[36m<span[39m
|
||
[33mclass[39m=[32m"little-dot"[39m
|
||
[36m/>[39m
|
||
[0m소리에 집중하는 시간[0m
|
||
[36m</div>[39m
|
||
[36m</header>[39m
|
||
[36m<main[39m
|
||
[33mclass[39m=[32m"wrap"[39m
|
||
[33mid[39m=[32m"main"[39m
|
||
[33mtabindex[39m=[32m"-1"[39m
|
||
[36m>[39m
|
||
[36m<section[39m
|
||
[33maria-label[39m=[32m"단어 찾기 게임"[39m
|
||
[33mclass[39m=[32m"game-layout"[39m
|
||
[36m>[39m
|
||
[36m<div[39m
|
||
[33mclass[39m=[32m"game-top"[39m
|
||
[36m>[39m
|
||
[36m<span[39m
|
||
[33mclass[39m=[32m"eyebrow"[39m
|
||
[36m>[39m
|
||
[0m나의 소리 탐험[0m
|
||
[36m</span>[39m
|
||
[36m<span>[39m
|
||
[0m문제 [0m
|
||
[36m<b>[39m
|
||
[0m01[0m
|
||
[36m</b>[39m
|
||
[0m /[0m
|
||
[0m [0m
|
||
[0m3[0m
|
||
[36m</span>[39m
|
||
[36m</div>[39m
|
||
[36m<progress[39m
|
||
[33maria-label[39m=[32m"전체 진행률"[39m
|
||
[33mmax[39m=[32m"3"[39m
|
||
[33mvalue[39m=[32m"0"[39m
|
||
[36m/>[39m
|
||
[36m<div[39m
|
||
[33mclass[39m=[32m"game-columns"[39m
|
||
[36m>[39m
|
||
[36m<aside[39m
|
||
[33mclass[39m=[32m"environment-panel"[39m
|
||
[36m>[39m
|
||
[36m<p[39m
|
||
[33mclass[39m=[32m"eyebrow"[39m
|
||
[36m>[39m
|
||
[0m지금 듣고 있는 공간[0m
|
||
[36m</p>[39m
|
||
[36m<h2>[39m
|
||
[0m카페[0m
|
||
[36m</h2>[39m
|
||
[36m<p>[39m
|
||
[0m부드러운 웅성임과 잔의 울림[0m
|
||
[36m</p>[39m
|
||
[36m<div[39m
|
||
[33maria-hidden[39m=[32m"true"[39m
|
||
[33mclass[39m=[32m"mascot small"[39m
|
||
[36m>[39m
|
||
[36m<span[39m
|
||
[33mclass[39m=[32m"ear left"[39m
|
||
[36m/>[39m
|
||
[36m<span[39m
|
||
[33mclass[39m=[32m"ear right"[39m
|
||
[36m/>[39m
|
||
[36m<span[39m
|
||
[33mclass[39m=[32m"eye left"[39m
|
||
[36m/>[39m
|
||
[36m<span[39m
|
||
[33mclass[39m=[32m"eye right"[39m
|
||
[36m/>[39m
|
||
[36m<span[39m
|
||
[33mclass[39m=[32m"smile"[39m
|
||
[36m/>[39m
|
||
[36m<b>[39m
|
||
[0mS[0m
|
||
[36m</b>[39m
|
||
[36m</div>[39m
|
||
[36m<div[39m
|
||
[33maria-hidden[39m=[32m"true"[39m
|
||
[33mclass[39m=[32m"sound-wave active"[39m
|
||
[36m>[39m
|
||
[36m<i[39m
|
||
[33mstyle[39m=[32m"height: 10px; animation-delay: 0s;"[39m
|
||
[36m/>[39m
|
||
[36m<i[39m
|
||
[33mstyle[39m=[32m"height: 33.799955450859244px; animation-delay: 0.05s;"[39m
|
||
[36m/>[39m
|
||
[36m<i[39m
|
||
[33mstyle[39m=[32m"height: 16.132986448643948px; animation-delay: 0.1s;"[39m
|
||
[36m/>[39m
|
||
[36m<i[39m
|
||
[33mstyle[39m=[32m"height: 32.219552375865575px; animation-delay: 0.15000000000000002s;"[39m
|
||
[36m/>[39m
|
||
[36m<i[39m
|
||
[33mstyle[39m=[32m"height: 21.858720427326595px; animation-delay: 0.2s;"[39m
|
||
[36m/>[39m
|
||
[36m<i[39m
|
||
[33mstyle[39m=[32m"height: 29.163690702963766px; animation-delay: 0.25s;"[39m
|
||
[36m/>[39m
|
||
[36m<i[39m
|
||
[33mstyle[39m=[32m"height: 26.796992502245015px; animation-delay: 0.30000000000000004s;"[39m
|
||
[36m/>[39m
|
||
[36m<i[39m
|
||
[33mstyle[39m=[32m"height: 24.835290693688798px; animation-delay: 0.35000000000000003s;"[39m
|
||
[36m/>[39m
|
||
[36m<i[39m
|
||
[33mstyle[39m=[32m"height: 30.619883556555898px; animation-delay: 0.4s;"[39m
|
||
[36m/>[39m
|
||
[36m<i[39m
|
||
[33mstyle[39m=[32m"height: 35.39139668035928px; animation-delay: 0.45s;"[39m
|
||
[36m/>[39m
|
||
[36m<i[39m
|
||
[33mstyle[39m=[32m"height: 71.52943948029164px; animation-delay: 0.5s;"[39m
|
||
[36m/>[39m
|
||
[36m<i[39m
|
||
[33mstyle[39m=[32m"height: 19.53593765210872px; animation-delay: 0.55s;"[39m
|
||
[36m/>[39m
|
||
[36m<i[39m
|
||
[33mstyle[39m=[32m"height: 73.98674560913082px; animation-delay: 0.6000000000000001s;"[39m
|
||
[36m/>[39m
|
||
[36m<i[39m
|
||
[33mstyle[39m=[32m"height: 16.952742107140878px; animation-delay: 0.65s;"[39m
|
||
[36m/>[39m
|
||
[36m<i[39m
|
||
[33mstyle[39m=[32m"height: 72.19510052760725px; animation-delay: 0.7000000000000001s;"[39m
|
||
[36m/>[39m
|
||
[36m<i[39m
|
||
[33mstyle[39m=[32m"height: 32.979734657418774px; animation-delay: 0.75s;"[39m
|
||
[36m/>[39m
|
||
[36m<i[39m
|
||
[33mstyle[39m=[32m"height: 66.27347594564635px; animation-delay: 0.8s;"[39m
|
||
[36m/>[39m
|
||
[36m<i[39m
|
||
[33mstyle[39m=[32m"height: 47.480789758355044px; animation-delay: 0.8500000000000001s;"[39m
|
||
[36m/>[39m
|
||
[36m<i[39m
|
||
[33mstyle[39m=[32m"height: 56.615089141222136px; animation-delay: 0.9s;"[39m
|
||
[36m/>[39m
|
||
[36m<i[39m
|
||
[33mstyle[39m=[32m"height: 59.492984932238116px; animation-delay: 0.9500000000000001s;"[39m
|
||
[36m/>[39m
|
||
[36m<i[39m
|
||
[33mstyle[39m=[32m"height: 43.861291911681526px; animation-delay: 1s;"[39m
|
||
[36m/>[39m
|
||
[36m<i[39m
|
||
[33mstyle[39m=[32m"height: 68.21866699734562px; animation-delay: 1.05s;"[39m
|
||
[36m/>[39m
|
||
[36m<i[39m
|
||
[33mstyle[39m=[32m"height: 28.858982496016484px; animation-delay: 1.1s;"[39m
|
||
[36m/>[39m
|
||
[36m<i[39m
|
||
[33mstyle[39m=[32m"height: 73.07841912260051px; animation-delay: 1.1500000000000001s;"[39m
|
||
[36m/>[39m
|
||
[36m<i[39m
|
||
[33mstyle[39m=[32m"height: 12.60436847039135px; animation-delay: 1.2000000000000002s;"[39m
|
||
[36m/>[39m
|
||
[36m<i[39m
|
||
[33mstyle[39m=[32m"height: 73.74953619965402px; animation-delay: 1.25s;"[39m
|
||
[36m/>[39m
|
||
[36m<i[39m
|
||
[33mstyle[39m=[32m"height: 23.8231850360459px; animation-delay: 1.3s;"[39m
|
||
[36m/>[39m
|
||
[36m<i[39m
|
||
[33mstyle[39m=[32m"height: 32.57029511072814px; animation-delay: 1.35s;"[39m
|
||
[36m/>[39m
|
||
[36m<i[39m
|
||
[33mstyle[39m=[32m"height: 20.99981090780238px; animation-delay: 1.4000000000000001s;"[39m
|
||
[36m/>[39m
|
||
[36m<i[39m
|
||
[33mstyle[39m=[32m"height: 29.735764963203792px; animation-delay: 1.4500000000000002s;"[39m
|
||
[36m/>[39m
|
||
[36m<i[39m
|
||
[33mstyle[39m=[32m"height: 26.085500220240995px; animation-delay: 1.5s;"[39m
|
||
[36m/>[39m
|
||
[36m<i[39m
|
||
[33mstyle[39m=[32m"height: 25.59070868046883px; animation-delay: 1.55s;"[39m
|
||
[36m/>[39m
|
||
[36m<i[39m
|
||
[33mstyle[39m=[32m"height: 30.10305417152866px; animation-delay: 1.6s;"[39m
|
||
[36m/>[39m
|
||
[36m<i[39m
|
||
[33mstyle[39m=[32m"height: 20.410372983416416px; animation-delay: 1.6500000000000001s;"[39m
|
||
[36m/>[39m
|
||
[36m<i[39m
|
||
[33mstyle[39m=[32m"height: 32.785692656480826px; animation-delay: 1.7000000000000002s;"[39m
|
||
[36m/>[39m
|
||
[36m</div>[39m
|
||
[36m<div[39m
|
||
[33mclass[39m=[32m"level-tag"[39m
|
||
[36m>[39m
|
||
[0m1[0m
|
||
[0m단계 · [0m
|
||
[0mSNR +6 dB[0m
|
||
[36m</div>[39m
|
||
[36m<p[39m
|
||
[33mclass[39m=[32m"db-note"[39m
|
||
[36m>[39m
|
||
[0m소리에 익숙해지기[0m
|
||
[36m</p>[39m
|
||
[36m<div[39m
|
||
[33mclass[39m=[32m"snr-control"[39m
|
||
[36m>[39m
|
||
[36m<label[39m
|
||
[33mfor[39m=[32m"snr"[39m
|
||
[36m>[39m
|
||
[0m목표 음성 SNR[0m
|
||
[36m</label>[39m
|
||
[36m<input[39m
|
||
[33maria-describedby[39m=[32m"snr-help"[39m
|
||
[33mid[39m=[32m"snr"[39m
|
||
[33mmax[39m=[32m"12"[39m
|
||
[33mmin[39m=[32m"-12"[39m
|
||
[33mstep[39m=[32m"1"[39m
|
||
[33mtype[39m=[32m"range"[39m
|
||
[33mvalue[39m=[32m"6"[39m
|
||
[36m/>[39m
|
||
[36m<output[39m
|
||
[33mfor[39m=[32m"snr"[39m
|
||
[36m>[39m
|
||
[0mSNR +6 dB[0m
|
||
[36m</output>[39m
|
||
[36m<p[39m
|
||
[33mid[39m=[32m"snr-help"[39m
|
||
[36m>[39m
|
||
[0m음성이 배경보다 6 dB 커요.[0m
|
||
[0m 범위 −12~+12 dB · 1 dB 간격. 양수는 음성이 더 크게, 0은 같게, 음수는 더 작게 들려요. 변경은 다음 재생·재청취부터 적용돼요.[0m
|
||
[36m</p>[39m
|
||
[36m</div>[39m
|
||
[36m<div[39m
|
||
[33mclass[39m=[32m"volume-row"[39m
|
||
[36m>[39m
|
||
[36m<label[39m
|
||
[33mfor[39m=[32m"volume"[39m
|
||
[36m>[39m
|
||
[36m<span[39m
|
||
[33maria-hidden[39m=[32m"true"[39m
|
||
[36m>[39m
|
||
[0m◖))[0m
|
||
[36m</span>[39m
|
||
[0m 전체 음량[0m
|
||
[36m</label>[39m
|
||
[36m<input[39m
|
||
[33mid[39m=[32m"volume"[39m
|
||
[33mmax[39m=[32m"100"[39m
|
||
[33mmin[39m=[32m"0"[39m
|
||
[33mtype[39m=[32m"range"[39m
|
||
[33mvalue[39m=[32m"35"[39m
|
||
[36m/>[39m
|
||
[36m<output[39m
|
||
[33mfor[39m=[32m"volume"[39m
|
||
[36m>[39m
|
||
[0m35[0m
|
||
[0m%[0m
|
||
[36m</output>[39m
|
||
[36m</div>[39m
|
||
[36m<div[39m
|
||
[33mclass[39m=[32m"mini-stats"[39m
|
||
[36m>[39m
|
||
[36m<span>[39m
|
||
[0m점수 [0m
|
||
[36m<b>[39m
|
||
[0m0[0m
|
||
[36m</b>[39m
|
||
[36m</span>[39m
|
||
[36m<span>[39m
|
||
[0m연속 정답 [0m
|
||
[36m<b>[39m
|
||
[0m0[0m
|
||
[36m</b>[39m
|
||
[36m</span>[39m
|
||
[36m</div>[39m
|
||
[36m</aside>[39m
|
||
[36m<div[39m
|
||
[33mclass[39m=[32m"question-panel panel"[39m
|
||
[36m>[39m
|
||
[36m<div[39m
|
||
[33mclass[39m=[32m"question-meta"[39m
|
||
[36m>[39m
|
||
[36m<span>[39m
|
||
[0m두 번의 힌트[0m
|
||
[36m</span>[39m
|
||
[36m<span>[39m
|
||
[0m객관식[0m
|
||
[36m</span>[39m
|
||
[36m</div>[39m
|
||
[36m<div[39m
|
||
[33mclass[39m=[32m"listening"[39m
|
||
[36m>[39m
|
||
[36m<span[39m
|
||
[33maria-hidden[39m=[32m"true"[39m
|
||
[33mclass[39m=[32m"listening-icon"[39m
|
||
[36m>[39m
|
||
[0m♬[0m
|
||
[36m</span>[39m
|
||
[36m<h2[39m
|
||
[33mtabindex[39m=[32m"-1"[39m
|
||
[36m>[39m
|
||
[0m소리 사이에 집중해 보세요.[0m
|
||
[36m</h2>[39m
|
||
[36m<p>[39m
|
||
[0m문장이 끝나면 질문이 나타나요.[0m
|
||
[36m<br />[39m
|
||
[0m작은 단어 하나를 기억해 주세요.[0m
|
||
[36m</p>[39m
|
||
[36m<p[39m
|
||
[33mrole[39m=[32m"status"[39m
|
||
[36m>[39m
|
||
[0m에스의 목소리를 듣고 있어요…[0m
|
||
[36m</p>[39m
|
||
[36m</div>[39m
|
||
[36m<div[39m
|
||
[33mclass[39m=[32m"play-controls"[39m
|
||
[36m>[39m
|
||
[36m<button[39m
|
||
[33mclass[39m=[32m"secondary"[39m
|
||
[33mdisabled[39m=[32m""[39m
|
||
[36m>[39m
|
||
[0m듣는 중…[0m
|
||
[36m</button>[39m
|
||
[36m<button[39m
|
||
[33mclass[39m=[32m"text-button"[39m
|
||
[36m>[39m
|
||
[0m듣기 중단[0m
|
||
[36m</button>[39m
|
||
[36m<small>[39m
|
||
[0m다시 들어도 점수는 줄어들지 않아요.[0m
|
||
[36m</small>[39m
|
||
[36m</div>[39m
|
||
[36m</div>[39m
|
||
[36m</div>[39m
|
||
[36m</section>[39m
|
||
[36m</main>[39m
|
||
[36m<footer[39m
|
||
[33mclass[39m=[32m"footer wrap"[39m
|
||
[36m>[39m
|
||
[36m<p>[39m
|
||
[0mDesigned by OZ at Heat-T Medical Inc.[0m
|
||
[36m</p>[39m
|
||
[36m<p>[39m
|
||
[0m청각적 주의·식별 게임 · 의료적 진단이나 치료를 제공하지 않습니다.[0m
|
||
[36m</p>[39m
|
||
[36m<span>[39m
|
||
[0m개인정보 수집 없이, 오직 플레이만.[0m
|
||
[36m</span>[39m
|
||
[36m<a[39m
|
||
[33mhref[39m=[32m"/AMBIENCE_NOTICES.md"[39m
|
||
[36m>[39m
|
||
[0m환경음 출처·라이선스[0m
|
||
[36m</a>[39m
|
||
[36m</footer>[39m
|
||
[36m</div>[39m
|
||
[36m</body>[39m
|
||
❯ Object.getElementError node_modules/@testing-library/dom/dist/config.js:37:19
|
||
❯ node_modules/@testing-library/dom/dist/query-helpers.js:76:38
|
||
❯ node_modules/@testing-library/dom/dist/query-helpers.js:52:17
|
||
❯ node_modules/@testing-library/dom/dist/query-helpers.js:95:19
|
||
❯ tests/App.test.tsx:518:24
|
||
516| await f.user.click(screen.getByRole("button", { name: "게임 시작 · 소리 듣기…
|
||
517| for (let index = 0; index < 3; index++) {
|
||
518| const bar = screen.getByRole("progressbar", { name: "현재 문항 진행률" });
|
||
| ^
|
||
519| expect(bar).toHaveAttribute("max", "3");
|
||
520| expect(bar).toHaveAttribute("value", String(index + 1));
|
||
|
||
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[4/8]⎯
|
||
|
||
FAIL tests/App.test.tsx > 무응답 종료는 정답률 대신 미응답 상태와 단계별 미진행을 보여 준다
|
||
TestingLibraryElementError: Unable to find an accessible element with the role "heading" and name "문제 풀이를 중간에 종료했어요."
|
||
|
||
Here are the accessible roles:
|
||
|
||
link:
|
||
|
||
Name "본문으로 건너뛰기":
|
||
[36m<a[39m
|
||
[33mclass[39m=[32m"skip-link"[39m
|
||
[33mhref[39m=[32m"#main"[39m
|
||
[36m/>[39m
|
||
|
||
Name "환경음 출처·라이선스":
|
||
[36m<a[39m
|
||
[33mhref[39m=[32m"/AMBIENCE_NOTICES.md"[39m
|
||
[36m/>[39m
|
||
|
||
--------------------------------------------------
|
||
banner:
|
||
|
||
Name "":
|
||
[36m<header[39m
|
||
[33mclass[39m=[32m"header wrap"[39m
|
||
[36m/>[39m
|
||
|
||
--------------------------------------------------
|
||
heading:
|
||
|
||
Name "단어를 맞춰라":
|
||
[36m<h1 />[39m
|
||
|
||
Name "문제 풀이를 종료했어요.":
|
||
[36m<h2[39m
|
||
[33mtabindex[39m=[32m"-1"[39m
|
||
[36m/>[39m
|
||
|
||
--------------------------------------------------
|
||
main:
|
||
|
||
Name "":
|
||
[36m<main[39m
|
||
[33mclass[39m=[32m"wrap"[39m
|
||
[33mid[39m=[32m"main"[39m
|
||
[33mtabindex[39m=[32m"-1"[39m
|
||
[36m/>[39m
|
||
|
||
--------------------------------------------------
|
||
paragraph:
|
||
|
||
Name "":
|
||
[36m<p[39m
|
||
[33mclass[39m=[32m"muted"[39m
|
||
[36m/>[39m
|
||
|
||
Name "":
|
||
[36m<p />[39m
|
||
|
||
Name "":
|
||
[36m<p[39m
|
||
[33mclass[39m=[32m"muted"[39m
|
||
[36m/>[39m
|
||
|
||
Name "":
|
||
[36m<p />[39m
|
||
|
||
Name "":
|
||
[36m<p />[39m
|
||
|
||
--------------------------------------------------
|
||
strong:
|
||
|
||
Name "":
|
||
[36m<strong />[39m
|
||
|
||
Name "":
|
||
[36m<strong />[39m
|
||
|
||
Name "":
|
||
[36m<strong />[39m
|
||
|
||
--------------------------------------------------
|
||
table:
|
||
|
||
Name "난이도별 결과":
|
||
[36m<table[39m
|
||
[33maria-label[39m=[32m"난이도별 결과"[39m
|
||
[36m/>[39m
|
||
|
||
--------------------------------------------------
|
||
rowgroup:
|
||
|
||
Name "":
|
||
[36m<thead />[39m
|
||
|
||
Name "":
|
||
[36m<tbody />[39m
|
||
|
||
--------------------------------------------------
|
||
row:
|
||
|
||
Name "난이도 SNR 맞힌 문제":
|
||
[36m<tr />[39m
|
||
|
||
Name "1단계 SNR +6 dB 0 / 0":
|
||
[36m<tr />[39m
|
||
|
||
Name "2단계 SNR +3 dB 0 / 0":
|
||
[36m<tr />[39m
|
||
|
||
Name "3단계 SNR 0 dB 0 / 0":
|
||
[36m<tr />[39m
|
||
|
||
Name "4단계 SNR -3 dB 0 / 0":
|
||
[36m<tr />[39m
|
||
|
||
Name "5단계 SNR -6 dB 0 / 0":
|
||
[36m<tr />[39m
|
||
|
||
--------------------------------------------------
|
||
columnheader:
|
||
|
||
Name "난이도":
|
||
[36m<th[39m
|
||
[33mscope[39m=[32m"col"[39m
|
||
[36m/>[39m
|
||
|
||
Name "SNR":
|
||
[36m<th[39m
|
||
[33mscope[39m=[32m"col"[39m
|
||
[36m/>[39m
|
||
|
||
Name "맞힌 문제":
|
||
[36m<th[39m
|
||
[33mscope[39m=[32m"col"[39m
|
||
[36m/>[39m
|
||
|
||
--------------------------------------------------
|
||
rowheader:
|
||
|
||
Name "1단계":
|
||
[36m<th[39m
|
||
[33mscope[39m=[32m"row"[39m
|
||
[36m/>[39m
|
||
|
||
Name "2단계":
|
||
[36m<th[39m
|
||
[33mscope[39m=[32m"row"[39m
|
||
[36m/>[39m
|
||
|
||
Name "3단계":
|
||
[36m<th[39m
|
||
[33mscope[39m=[32m"row"[39m
|
||
[36m/>[39m
|
||
|
||
Name "4단계":
|
||
[36m<th[39m
|
||
[33mscope[39m=[32m"row"[39m
|
||
[36m/>[39m
|
||
|
||
Name "5단계":
|
||
[36m<th[39m
|
||
[33mscope[39m=[32m"row"[39m
|
||
[36m/>[39m
|
||
|
||
--------------------------------------------------
|
||
cell:
|
||
|
||
Name "SNR +6 dB":
|
||
[36m<td />[39m
|
||
|
||
Name "0 / 0":
|
||
[36m<td />[39m
|
||
|
||
Name "SNR +3 dB":
|
||
[36m<td />[39m
|
||
|
||
Name "0 / 0":
|
||
[36m<td />[39m
|
||
|
||
Name "SNR 0 dB":
|
||
[36m<td />[39m
|
||
|
||
Name "0 / 0":
|
||
[36m<td />[39m
|
||
|
||
Name "SNR -3 dB":
|
||
[36m<td />[39m
|
||
|
||
Name "0 / 0":
|
||
[36m<td />[39m
|
||
|
||
Name "SNR -6 dB":
|
||
[36m<td />[39m
|
||
|
||
Name "0 / 0":
|
||
[36m<td />[39m
|
||
|
||
--------------------------------------------------
|
||
button:
|
||
|
||
Name "처음 화면으로":
|
||
[36m<button[39m
|
||
[33mclass[39m=[32m"secondary"[39m
|
||
[36m/>[39m
|
||
|
||
--------------------------------------------------
|
||
slider:
|
||
|
||
Name "전체 음량":
|
||
[36m<input[39m
|
||
[33mid[39m=[32m"volume"[39m
|
||
[33mmax[39m=[32m"100"[39m
|
||
[33mmin[39m=[32m"0"[39m
|
||
[33mtype[39m=[32m"range"[39m
|
||
[33mvalue[39m=[32m"35"[39m
|
||
[36m/>[39m
|
||
|
||
--------------------------------------------------
|
||
status:
|
||
|
||
Name "":
|
||
[36m<output[39m
|
||
[33mfor[39m=[32m"volume"[39m
|
||
[36m/>[39m
|
||
|
||
--------------------------------------------------
|
||
contentinfo:
|
||
|
||
Name "":
|
||
[36m<footer[39m
|
||
[33mclass[39m=[32m"footer wrap"[39m
|
||
[36m/>[39m
|
||
|
||
--------------------------------------------------
|
||
|
||
Ignored nodes: comments, script, style
|
||
[36m<body>[39m
|
||
[36m<div>[39m
|
||
[36m<a[39m
|
||
[33mclass[39m=[32m"skip-link"[39m
|
||
[33mhref[39m=[32m"#main"[39m
|
||
[36m>[39m
|
||
[0m본문으로 건너뛰기[0m
|
||
[36m</a>[39m
|
||
[36m<header[39m
|
||
[33mclass[39m=[32m"header wrap"[39m
|
||
[36m>[39m
|
||
[36m<div[39m
|
||
[33mclass[39m=[32m"brand"[39m
|
||
[36m>[39m
|
||
[36m<span[39m
|
||
[33maria-hidden[39m=[32m"true"[39m
|
||
[33mclass[39m=[32m"brand-mark"[39m
|
||
[36m>[39m
|
||
[36m<i />[39m
|
||
[36m<i />[39m
|
||
[36m<i />[39m
|
||
[36m<i />[39m
|
||
[36m</span>[39m
|
||
[36m<h1>[39m
|
||
[0m단어를 맞춰라[0m
|
||
[36m</h1>[39m
|
||
[36m<span[39m
|
||
[33mclass[39m=[32m"version"[39m
|
||
[36m>[39m
|
||
[0mv0.2.3[0m
|
||
[36m</span>[39m
|
||
[36m</div>[39m
|
||
[36m<div[39m
|
||
[33mclass[39m=[32m"header-actions"[39m
|
||
[36m>[39m
|
||
[36m<span[39m
|
||
[33mclass[39m=[32m"little-dot"[39m
|
||
[36m/>[39m
|
||
[0m소리에 집중하는 시간[0m
|
||
[36m</div>[39m
|
||
[36m</header>[39m
|
||
[36m<main[39m
|
||
[33mclass[39m=[32m"wrap"[39m
|
||
[33mid[39m=[32m"main"[39m
|
||
[33mtabindex[39m=[32m"-1"[39m
|
||
[36m>[39m
|
||
[36m<section[39m
|
||
[33mclass[39m=[32m"results-panel panel"[39m
|
||
[36m>[39m
|
||
[36m<span[39m
|
||
[33mclass[39m=[32m"eyebrow"[39m
|
||
[36m>[39m
|
||
[0m지금까지의 소리 탐험[0m
|
||
[36m</span>[39m
|
||
[36m<div[39m
|
||
[33mclass[39m=[32m"result-mascot"[39m
|
||
[36m>[39m
|
||
[36m<div[39m
|
||
[33maria-hidden[39m=[32m"true"[39m
|
||
[33mclass[39m=[32m"mascot small"[39m
|
||
[36m>[39m
|
||
[36m<span[39m
|
||
[33mclass[39m=[32m"ear left"[39m
|
||
[36m/>[39m
|
||
[36m<span[39m
|
||
[33mclass[39m=[32m"ear right"[39m
|
||
[36m/>[39m
|
||
[36m<span[39m
|
||
[33mclass[39m=[32m"eye left"[39m
|
||
[36m/>[39m
|
||
[36m<span[39m
|
||
[33mclass[39m=[32m"eye right"[39m
|
||
[36m/>[39m
|
||
[36m<span[39m
|
||
[33mclass[39m=[32m"smile"[39m
|
||
[36m/>[39m
|
||
[36m<b>[39m
|
||
[0mS[0m
|
||
[36m</b>[39m
|
||
[36m</div>[39m
|
||
[36m</div>[39m
|
||
[36m<h2[39m
|
||
[33mtabindex[39m=[32m"-1"[39m
|
||
[36m>[39m
|
||
[0m문제 풀이를 종료했어요.[0m
|
||
[36m</h2>[39m
|
||
[36m<p[39m
|
||
[33mclass[39m=[32m"muted"[39m
|
||
[36m>[39m
|
||
[0m작은 소리에 집중한 당신, 다음 탐험에서도 만나요.[0m
|
||
[36m</p>[39m
|
||
[36m<p>[39m
|
||
[0m응답 [0m
|
||
[0m0[0m
|
||
[0m문항 · 정답 [0m
|
||
[0m0[0m
|
||
[0m문항[0m
|
||
[36m</p>[39m
|
||
[36m<div[39m
|
||
[33mclass[39m=[32m"stats"[39m
|
||
[36m>[39m
|
||
[36m<div>[39m
|
||
[36m<strong>[39m
|
||
[0m0[0m
|
||
[36m</strong>[39m
|
||
[36m<span>[39m
|
||
[0m총 점수[0m
|
||
[36m</span>[39m
|
||
[36m</div>[39m
|
||
[36m<div>[39m
|
||
[36m<strong>[39m
|
||
[0m0[0m
|
||
[0m%[0m
|
||
[36m</strong>[39m
|
||
[36m<span>[39m
|
||
[0m정답률 · [0m
|
||
[0m0[0m
|
||
[0m/[0m
|
||
[0m0[0m
|
||
[36m</span>[39m
|
||
[36m</div>[39m
|
||
[36m<div>[39m
|
||
[36m<strong>[39m
|
||
[0m0[0m
|
||
[36m<small>[39m
|
||
[0m회[0m
|
||
[36m</small>[39m
|
||
[36m</strong>[39m
|
||
[36m<span>[39m
|
||
[0m최고 연속 정답[0m
|
||
[36m</span>[39m
|
||
[36m</div>[39m
|
||
[36m</div>[39m
|
||
[36m<table[39m
|
||
[33maria-label[39m=[32m"난이도별 결과"[39m
|
||
[36m>[39m
|
||
[36m<thead>[39m
|
||
[36m<tr>[39m
|
||
[36m<th[39m
|
||
[33mscope[39m=[32m"col"[39m
|
||
[36m>[39m
|
||
[0m난이도[0m
|
||
[36m</th>[39m
|
||
[36m<th[39m
|
||
[33mscope[39m=[32m"col"[39m
|
||
[36m>[39m
|
||
[0mSNR[0m
|
||
[36m</th>[39m
|
||
[36m<th[39m
|
||
[33mscope[39m=[32m"col"[39m
|
||
[36m>[39m
|
||
[0m맞힌 문제[0m
|
||
[36m</th>[39m
|
||
[36m</tr>[39m
|
||
[36m</thead>[39m
|
||
[36m<tbody>[39m
|
||
[36m<tr>[39m
|
||
[36m<th[39m
|
||
[33mscope[39m=[32m"row"[39m
|
||
[36m>[39m
|
||
[0m1[0m
|
||
[0m단계[0m
|
||
[36m</th>[39m
|
||
[36m<td>[39m
|
||
[0mSNR +6 dB[0m
|
||
[36m</td>[39m
|
||
[36m<td>[39m
|
||
[0m0[0m
|
||
[0m / [0m
|
||
[0m0[0m
|
||
[36m</td>[39m
|
||
[36m</tr>[39m
|
||
[36m<tr>[39m
|
||
[36m<th[39m
|
||
[33mscope[39m=[32m"row"[39m
|
||
[36m>[39m
|
||
[0m2[0m
|
||
[0m단계[0m
|
||
[36m</th>[39m
|
||
[36m<td>[39m
|
||
[0mSNR +3 dB[0m
|
||
[36m</td>[39m
|
||
[36m<td>[39m
|
||
[0m0[0m
|
||
[0m / [0m
|
||
[0m0[0m
|
||
[36m</td>[39m
|
||
[36m</tr>[39m
|
||
[36m<tr>[39m
|
||
[36m<th[39m
|
||
[33mscope[39m=[32m"row"[39m
|
||
[36m>[39m
|
||
[0m3[0m
|
||
[0m단계[0m
|
||
[36m</th>[39m
|
||
[36m<td>[39m
|
||
[0mSNR 0 dB[0m
|
||
[36m</td>[39m
|
||
[36m<td>[39m
|
||
[0m0[0m
|
||
[0m / [0m
|
||
[0m0[0m
|
||
[36m</td>[39m
|
||
[36m</tr>[39m
|
||
[36m<tr>[39m
|
||
[36m<th[39m
|
||
[33mscope[39m=[32m"row"[39m
|
||
[36m>[39m
|
||
[0m4[0m
|
||
[0m단계[0m
|
||
[36m</th>[39m
|
||
[36m<td>[39m
|
||
[0mSNR -3 dB[0m
|
||
[36m</td>[39m
|
||
[36m<td>[39m
|
||
[0m0[0m
|
||
[0m / [0m
|
||
[0m0[0m
|
||
[36m</td>[39m
|
||
[36m</tr>[39m
|
||
[36m<tr>[39m
|
||
[36m<th[39m
|
||
[33mscope[39m=[32m"row"[39m
|
||
[36m>[39m
|
||
[0m5[0m
|
||
[0m단계[0m
|
||
[36m</th>[39m
|
||
[36m<td>[39m
|
||
[0mSNR -6 dB[0m
|
||
[36m</td>[39m
|
||
[36m<td>[39m
|
||
[0m0[0m
|
||
[0m / [0m
|
||
[0m0[0m
|
||
[36m</td>[39m
|
||
[36m</tr>[39m
|
||
[36m</tbody>[39m
|
||
[36m</table>[39m
|
||
[36m<p[39m
|
||
[33mclass[39m=[32m"muted"[39m
|
||
[36m>[39m
|
||
[0m단계 × 100점 + 연속 정답 보너스 (라운드 내 최대[0m
|
||
[0m [0m
|
||
[0m20[0m
|
||
[0m점)[0m
|
||
[36m</p>[39m
|
||
[36m<button[39m
|
||
[33mclass[39m=[32m"secondary"[39m
|
||
[36m>[39m
|
||
[0m처음 화면으로[0m
|
||
[36m</button>[39m
|
||
[36m</section>[39m
|
||
[36m<div[39m
|
||
[33mclass[39m=[32m"volume-row"[39m
|
||
[36m>[39m
|
||
[36m<label[39m
|
||
[33mfor[39m=[32m"volume"[39m
|
||
[36m>[39m
|
||
[36m<span[39m
|
||
[33maria-hidden[39m=[32m"true"[39m
|
||
[36m>[39m
|
||
[0m◖))[0m
|
||
[36m</span>[39m
|
||
[0m 전체 음량[0m
|
||
[36m</label>[39m
|
||
[36m<input[39m
|
||
[33mid[39m=[32m"volume"[39m
|
||
[33mmax[39m=[32m"100"[39m
|
||
[33mmin[39m=[32m"0"[39m
|
||
[33mtype[39m=[32m"range"[39m
|
||
[33mvalue[39m=[32m"35"[39m
|
||
[36m/>[39m
|
||
[36m<output[39m
|
||
[33mfor[39m=[32m"volume"[39m
|
||
[36m>[39m
|
||
[0m35[0m
|
||
[0m%[0m
|
||
[36m</output>[39m
|
||
[36m</div>[39m
|
||
[36m</main>[39m
|
||
[36m<footer[39m
|
||
[33mclass[39m=[32m"footer wrap"[39m
|
||
[36m>[39m
|
||
[36m<p>[39m
|
||
[0mDesigned by OZ at Heat-T Medical Inc.[0m
|
||
[36m</p>[39m
|
||
[36m<p>[39m
|
||
[0m청각적 주의·식별 게임 · 의료적 진단이나 치료를 제공하지 않습니다.[0m
|
||
[36m</p>[39m
|
||
[36m<span>[39m
|
||
[0m개인정보 수집 없이, 오직 플레이만.[0m
|
||
[36m</span>[39m
|
||
[36m<a[39m
|
||
[33mhref[39m=[32m"/AMBIENCE_NOTICES.md"[39m
|
||
[36m>[39m
|
||
[0m환경음 출처·라이선스[0m
|
||
[36m</a>[39m
|
||
[36m</footer>[39m
|
||
[36m</div>[39m
|
||
[36m</body>[39m
|
||
❯ Object.getElementError node_modules/@testing-library/dom/dist/config.js:37:19
|
||
❯ node_modules/@testing-library/dom/dist/query-helpers.js:76:38
|
||
❯ node_modules/@testing-library/dom/dist/query-helpers.js:52:17
|
||
❯ node_modules/@testing-library/dom/dist/query-helpers.js:95:19
|
||
❯ tests/App.test.tsx:538:17
|
||
536| await f.user.click(screen.getByRole("button", { name: "게임 시작 · 소리 듣기…
|
||
537| await f.user.click(screen.getByRole("button", { name: "문제 풀이 종료" }));
|
||
538| expect(screen.getByRole("heading", { name: "문제 풀이를 중간에 종료했어요." })).t…
|
||
| ^
|
||
539| expect(screen.getByText("—")).toBeInTheDocument();
|
||
540| expect(screen.getByText("정답률 · 응답 없음")).toBeInTheDocument();
|
||
|
||
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[5/8]⎯
|
||
|
||
FAIL tests/neural-release.test.ts > README는 현재 리뷰 증거 경로와 정확한 라운드 보너스를 안내한다
|
||
AssertionError: expected '# 단어를 맞춰라 · Find-Word v0.2.3\n\n소음 속에…' to contain '.agent/evidence-v0.2.3/review-fixes/'
|
||
|
||
- Expected
|
||
+ Received
|
||
|
||
- .agent/evidence-v0.2.3/review-fixes/
|
||
+ # 단어를 맞춰라 · Find-Word v0.2.3
|
||
+
|
||
+ 소음 속에 숨은 한국어 단어를 듣고 찾는 반응형 웹 게임입니다.
|
||
+
|
||
+ **Designed by OZ at Heat-T Medical Inc.**
|
||
+
|
||
+ Canonical repository: [OZ-Group/Find-Word](https://source.ibit.kr/OZ-Group/Find-Word).
|
||
+ 프로젝트 자체는 **private / all-rights-reserved**이며 `package.json`의
|
||
+ `license`는 `UNLICENSED`입니다. [LICENSE](LICENSE)를 참고하세요.
|
||
+ 런타임 의존성 React, ReactDOM, scheduler의 MIT 전문은
|
||
+ [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md)에 보존하며,
|
||
+ `public/THIRD_PARTY_NOTICES.md`가 빌드 시 `dist/THIRD_PARTY_NOTICES.md`로 복사됩니다.
|
||
+ 빌드 검증기는 설치된 의존성의 라이선스 전문·버전과 세 사본을 대조합니다.
|
||
+
|
||
+ React + TypeScript strict + Vite로 만든 정적 SPA입니다. 로그인, 개인정보 저장,
|
||
+ 분석 도구, 외부 CDN, 런타임 TTS/API 요청이 없습니다. 청각적 주의·식별 게임이며
|
||
+ 의료적 진단·치료나 효과를 주장하지 않습니다.
|
||
+
|
||
+ ## 실행
|
||
+
|
||
+ Node.js 최소 버전은 **22.22.2** (`>=22.22.2`)입니다. 잠긴 jsdom 계열 의존성이
|
||
+ 요구하는 지원 범위는 22.x의 22.22.2 이상, 24.x의 24.15.0 이상 또는 26.0.0 이상입니다.
|
||
+ 이 중 지원되는 LTS 버전을 사용하세요. `package-lock.json`을
|
||
+ 포함하므로 새 환경에서는 `npm ci`를 사용합니다. 이번 검증 환경은 Node 26.7.0입니다.
|
||
+
|
||
+ ```bash
|
||
+ npm ci
|
||
+ npm run dev
|
||
+ ```
|
||
+
|
||
+ 표시되는 `http://127.0.0.1:5173`에서 사용합니다. 소리는 사용자가 **게임 시작 · 소리 듣기**를
|
||
+ 누른 뒤에만 재생합니다. 낮은 음량부터 조절하고 헤드폰이나 스피커를 사용할 수 있습니다.
|
||
+
|
||
+ ## 플레이
|
||
+
|
||
+ - 골고루 풀기, 보기에서 선택, 직접 입력 중 선택합니다.
|
||
+ - 8개 실제 현장 녹음 환경 중 하나를 지정하거나 라운드마다 섞어 세 곳을 방문합니다.
|
||
+ - 에스의 안내가 배경에 묻힌 뒤 목표 문장이 나옵니다. 재생 후 질문에 답합니다.
|
||
+ - 시작 난이도 1~5를 고르고 정확히 **3문항**을 같은 단계에서 풉니다. 단계 기본값은 **SNR +6, +3, 0, −3, −6 dB**입니다.
|
||
+ - 목표 음성 SNR을 **−12~+12 dB, 1 dB 간격**으로 직접 조절할 수 있습니다. 재생 중 변경은 다음 재생·재청취와 남은 문제부터 적용합니다.
|
||
+ 양수는 음성이 배경보다 크고, 0은 같고, 음수는 더 작다는 뜻입니다.
|
||
+ - 다시 듣기는 감점하지 않습니다. 정답은 `단계 × 100점`, 연속 정답은 라운드 내 최대 20점의 보너스를 받습니다.
|
||
+ - 정상 결과에서 다음 단계의 새 3문항을 바로 시작합니다. 5단계에서는 같은 단계 재도전과 홈 복귀를 제공합니다. 수동 SNR은 다음 라운드에도 유지되고, 홈 복귀 시 선택한 시작 단계의 기본값으로 돌아갑니다.
|
||
+ - 언제든 **문제 풀이 종료**를 누르면 즉시 오디오를 취소하고 **응답 수·정답 수**를 보여 줍니다. 무응답은 오답으로 세지 않으며 결과에서 **처음 화면으로** 돌아갑니다.
|
||
+ - 결과의 SNR은 실제 마지막 청취값을 기록합니다. 점수·정답률·최고 연속 정답·단계별 결과를 확인합니다.
|
||
+ - 새로고침하면 기록이 사라집니다. 결과를 브라우저나 서버에 저장하지 않습니다.
|
||
+
|
||
+ 10개 유형 × 10개 단어의 100개 목표 문장을 저장했습니다. 각 세션은 유형과
|
||
+ 단어를 섞어 출제하며 정답 위치도 섞습니다. 사전 표제어와 변형 규칙은
|
||
+ [WORDS.md](docs/WORDS.md)에 설명했습니다.
|
||
+ 청취 과제는 직접 목표 식별, 연습 암호와 진짜 암호 구별, 앞 단어를 잊고 다음
|
||
+ 단어 기억, 첫째·마지막·가운데 선택, 반복 찾기, 정정 반영, 신호 조건 적용,
|
||
+ 오른쪽 표지 선택의 10가지입니다. 문장에 실제 보기의 오답도 포함됩니다.
|
||
+
|
||
+ ## 검증과 정적 빌드
|
||
+
|
||
+ ```bash
|
||
+ npm run lint
|
||
+ npm test
|
||
+ python3 -m unittest discover -s tests/python -v
|
||
+ npm run build
|
||
+ npm audit
|
||
+ npm run preview
|
||
+ ```
|
||
+
|
||
+ `lint`는 ESLint와 TypeScript 검사, `test`는 unit/component/자산/빌드 검증기
|
||
+ 테스트를 실행합니다. `build`는 `dist/`를 만들고 음성 101개와 현장음 8개가 manifest 해시 그대로
|
||
+ 포함되었는지 확인합니다. 빌드에는 음성 합성 도구가 필요하지 않습니다.
|
||
+ 런타임 MIT notice와 현장음 attribution/license notice가 `dist/`에 전문 그대로 포함되는지도 검증합니다.
|
||
+
|
||
+ 실제 오디오·360px/1280px 화면·키보드·접근성·오류 재시도 검증:
|
||
+
|
||
+ ```bash
|
||
+ # Chromium이 없는 개발 환경에서 한 번만 실행합니다.
|
||
+ npx playwright install chromium
|
||
+ npm run test:browser
|
||
+ # 이미 설치된 Chrome을 사용할 때의 대안입니다.
|
||
+ CHROME_PATH=/usr/bin/google-chrome npm run test:browser
|
||
+ ```
|
||
+
|
||
+ Chromium sandbox는 기본으로 켭니다. sandbox를 지원하지 않는 격리된 개발
|
||
+ 환경에서만 `PLAYWRIGHT_NO_SANDBOX=1`을 명시해 끌 수 있습니다. `0`, `false`,
|
||
+ 빈 값이나 미설정은 sandbox를 유지합니다. `CHROME_PATH` 지정은 sandbox를 끄지 않습니다.
|
||
+
|
||
+ 브라우저 테스트는 기존 `dist/`를 사용하므로 소스 변경 후 먼저 빌드하세요.
|
||
+ 실제 음성 재생이 끝나기를 기다려 몇 분이 걸립니다. 로컬 4173 포트를
|
||
+ 테스트 중에만 열고 종료합니다. 스크린샷과 109개 WAV의 query URL·해시·디코드
|
||
+ 결과는 `test-results/`에 저장합니다. 인수 기록은 실행별 새 evidence 경로에
|
||
+ 복사하여 `.agent/evidence-v0.1.1/`의 과거 결과를 보존합니다.
|
||
+
|
||
+ ## 음성과 문서
|
||
+
|
||
+ 한국어 WAV 101개는 직접 쓴 문장을 Microsoft Edge online TTS의
|
||
+ `ko-KR-HyunsuMultilingualNeural`로 v0.1.1에서 생성했으며 WAV 바이트는 그대로 보존했습니다. edge-tts **7.3.1**,
|
||
+ rate `-6%`, pitch `-4Hz`이며 FFmpeg로 **24kHz mono PCM16**으로 변환합니다.
|
||
+ 생성 시 네트워크가 필요하며 앱은 저장된 WAV만 재생합니다. 환경음은 공개 라이선스의 실제 현장 녹음 8개를 각 12초로 변환해 번들합니다. 생성 음성의 독점 권리를 주장하지 않습니다.
|
||
+
|
||
+ intro와 목표 WAV는 모두 `/audio/파일명.wav?v=0.2.3`로 요청합니다.
|
||
+ `src/audio/assets.ts`의 자산 버전 한 곳을 사용하며, 같은 파일명으로 음성을
|
||
+ 교체할 때 이 값을 갱신해 기존 7일 캐시와 구분합니다. 배경은 `/ambience/환경.wav?v=0.2.3`입니다. 제품 버전은 0.2.3입니다.
|
||
+
|
||
+ Linux에서 Python 3.11 이상과 FFmpeg를 준비한 뒤 다음 명령을 사용합니다.
|
||
+ 클라이언트 버전을 고정해도 원격 모델 변경으로 동일 바이트 재생성은 보장하지 않습니다.
|
||
+
|
||
+ ```bash
|
||
+ python3 -m venv .venv-audio
|
||
+ .venv-audio/bin/python -m pip install -r requirements-audio.txt
|
||
+ .venv-audio/bin/python -m pip check
|
||
+ npm run audio:generate
|
||
+ ```
|
||
+
|
||
+ 고정 venv의 Python이 101개 모두 임시 생성·검증하고 디렉터리를 원자 교체합니다.
|
||
+ 요청별 60초 제한과 최대 3회 시도를 적용하며, 실패 시 기존 자산을 보존합니다.
|
||
+ 청취 샘플: [안내](public/audio/intro.wav), [행운의 사과](public/audio/luck-apple.wav).
|
||
+ 생성 방법, 도구 라이선스, 합성 음질의 한계는 [AUDIO_PROVENANCE.md](docs/AUDIO_PROVENANCE.md)를
|
||
+ 참고하세요. 실제 음량은 출력 장치에 따라 달라지며 표기 dB는 디지털 상대값입니다.
|
||
+
|
||
+ 현장음 원본은 `/tmp/findword-ambience-sources`에서만 보관하고 배포하지 않습니다.
|
||
+ `python3 scripts/ambience_audio.py`로 검증된 원본의 파생본과 manifest를 재현합니다.
|
||
+ PD·CC0·CC BY 4.0·CC BY-SA 4.0의 정확한 출처·저작자·변환·해시는
|
||
+ [현장음 manifest](public/ambience/manifest.json), [배포 고지](public/AMBIENCE_NOTICES.md)에 있습니다.
|
||
+ 시장 파생본은 CC BY-SA 4.0을 유지합니다. 외부 링크는 출처 확인용이며 앱은 이를 요청하지 않습니다.
|
||
+
|
||
+ - [변경 이력](CHANGELOG.md)
|
||
+ - [v0.2.3 구현·검증 결과](.agent/RESULT-v0.2.3.md)
|
||
+ - [설계와 상태 전이](docs/ARCHITECTURE.md)
|
||
+ - [Neo를 위한 정적 배포 안내](docs/DEPLOYMENT.md)
|
||
+ - [v0.1.1 RED/GREEN 및 실제 검증 결과](.agent/RESULT-v0.1.1.md)
|
||
+ - [v0.1 역사 기록](.agent/RESULT.md)
|
||
+
|
||
+ 이번 작업에서는 서버 배포와 Git commit/push를 실행하지 않습니다.
|
||
+
|
||
|
||
❯ tests/neural-release.test.ts:72:20
|
||
70| it("README는 현재 리뷰 증거 경로와 정확한 라운드 보너스를 안내한다", () => {
|
||
71| const doc = readFileSync("README.md", "utf8");
|
||
72| expect.soft(doc).toContain(".agent/evidence-v0.2.3/review-fixes/");
|
||
| ^
|
||
73| expect.soft(doc).toContain("문항별 최대 20점, 라운드 합계 최대 30점");
|
||
74| });
|
||
|
||
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[6/8]⎯
|
||
|
||
FAIL tests/neural-release.test.ts > README는 현재 리뷰 증거 경로와 정확한 라운드 보너스를 안내한다
|
||
AssertionError: expected '# 단어를 맞춰라 · Find-Word v0.2.3\n\n소음 속에…' to contain '문항별 최대 20점, 라운드 합계 최대 30점'
|
||
|
||
- Expected
|
||
+ Received
|
||
|
||
- 문항별 최대 20점, 라운드 합계 최대 30점
|
||
+ # 단어를 맞춰라 · Find-Word v0.2.3
|
||
+
|
||
+ 소음 속에 숨은 한국어 단어를 듣고 찾는 반응형 웹 게임입니다.
|
||
+
|
||
+ **Designed by OZ at Heat-T Medical Inc.**
|
||
+
|
||
+ Canonical repository: [OZ-Group/Find-Word](https://source.ibit.kr/OZ-Group/Find-Word).
|
||
+ 프로젝트 자체는 **private / all-rights-reserved**이며 `package.json`의
|
||
+ `license`는 `UNLICENSED`입니다. [LICENSE](LICENSE)를 참고하세요.
|
||
+ 런타임 의존성 React, ReactDOM, scheduler의 MIT 전문은
|
||
+ [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md)에 보존하며,
|
||
+ `public/THIRD_PARTY_NOTICES.md`가 빌드 시 `dist/THIRD_PARTY_NOTICES.md`로 복사됩니다.
|
||
+ 빌드 검증기는 설치된 의존성의 라이선스 전문·버전과 세 사본을 대조합니다.
|
||
+
|
||
+ React + TypeScript strict + Vite로 만든 정적 SPA입니다. 로그인, 개인정보 저장,
|
||
+ 분석 도구, 외부 CDN, 런타임 TTS/API 요청이 없습니다. 청각적 주의·식별 게임이며
|
||
+ 의료적 진단·치료나 효과를 주장하지 않습니다.
|
||
+
|
||
+ ## 실행
|
||
+
|
||
+ Node.js 최소 버전은 **22.22.2** (`>=22.22.2`)입니다. 잠긴 jsdom 계열 의존성이
|
||
+ 요구하는 지원 범위는 22.x의 22.22.2 이상, 24.x의 24.15.0 이상 또는 26.0.0 이상입니다.
|
||
+ 이 중 지원되는 LTS 버전을 사용하세요. `package-lock.json`을
|
||
+ 포함하므로 새 환경에서는 `npm ci`를 사용합니다. 이번 검증 환경은 Node 26.7.0입니다.
|
||
+
|
||
+ ```bash
|
||
+ npm ci
|
||
+ npm run dev
|
||
+ ```
|
||
+
|
||
+ 표시되는 `http://127.0.0.1:5173`에서 사용합니다. 소리는 사용자가 **게임 시작 · 소리 듣기**를
|
||
+ 누른 뒤에만 재생합니다. 낮은 음량부터 조절하고 헤드폰이나 스피커를 사용할 수 있습니다.
|
||
+
|
||
+ ## 플레이
|
||
+
|
||
+ - 골고루 풀기, 보기에서 선택, 직접 입력 중 선택합니다.
|
||
+ - 8개 실제 현장 녹음 환경 중 하나를 지정하거나 라운드마다 섞어 세 곳을 방문합니다.
|
||
+ - 에스의 안내가 배경에 묻힌 뒤 목표 문장이 나옵니다. 재생 후 질문에 답합니다.
|
||
+ - 시작 난이도 1~5를 고르고 정확히 **3문항**을 같은 단계에서 풉니다. 단계 기본값은 **SNR +6, +3, 0, −3, −6 dB**입니다.
|
||
+ - 목표 음성 SNR을 **−12~+12 dB, 1 dB 간격**으로 직접 조절할 수 있습니다. 재생 중 변경은 다음 재생·재청취와 남은 문제부터 적용합니다.
|
||
+ 양수는 음성이 배경보다 크고, 0은 같고, 음수는 더 작다는 뜻입니다.
|
||
+ - 다시 듣기는 감점하지 않습니다. 정답은 `단계 × 100점`, 연속 정답은 라운드 내 최대 20점의 보너스를 받습니다.
|
||
+ - 정상 결과에서 다음 단계의 새 3문항을 바로 시작합니다. 5단계에서는 같은 단계 재도전과 홈 복귀를 제공합니다. 수동 SNR은 다음 라운드에도 유지되고, 홈 복귀 시 선택한 시작 단계의 기본값으로 돌아갑니다.
|
||
+ - 언제든 **문제 풀이 종료**를 누르면 즉시 오디오를 취소하고 **응답 수·정답 수**를 보여 줍니다. 무응답은 오답으로 세지 않으며 결과에서 **처음 화면으로** 돌아갑니다.
|
||
+ - 결과의 SNR은 실제 마지막 청취값을 기록합니다. 점수·정답률·최고 연속 정답·단계별 결과를 확인합니다.
|
||
+ - 새로고침하면 기록이 사라집니다. 결과를 브라우저나 서버에 저장하지 않습니다.
|
||
+
|
||
+ 10개 유형 × 10개 단어의 100개 목표 문장을 저장했습니다. 각 세션은 유형과
|
||
+ 단어를 섞어 출제하며 정답 위치도 섞습니다. 사전 표제어와 변형 규칙은
|
||
+ [WORDS.md](docs/WORDS.md)에 설명했습니다.
|
||
+ 청취 과제는 직접 목표 식별, 연습 암호와 진짜 암호 구별, 앞 단어를 잊고 다음
|
||
+ 단어 기억, 첫째·마지막·가운데 선택, 반복 찾기, 정정 반영, 신호 조건 적용,
|
||
+ 오른쪽 표지 선택의 10가지입니다. 문장에 실제 보기의 오답도 포함됩니다.
|
||
+
|
||
+ ## 검증과 정적 빌드
|
||
+
|
||
+ ```bash
|
||
+ npm run lint
|
||
+ npm test
|
||
+ python3 -m unittest discover -s tests/python -v
|
||
+ npm run build
|
||
+ npm audit
|
||
+ npm run preview
|
||
+ ```
|
||
+
|
||
+ `lint`는 ESLint와 TypeScript 검사, `test`는 unit/component/자산/빌드 검증기
|
||
+ 테스트를 실행합니다. `build`는 `dist/`를 만들고 음성 101개와 현장음 8개가 manifest 해시 그대로
|
||
+ 포함되었는지 확인합니다. 빌드에는 음성 합성 도구가 필요하지 않습니다.
|
||
+ 런타임 MIT notice와 현장음 attribution/license notice가 `dist/`에 전문 그대로 포함되는지도 검증합니다.
|
||
+
|
||
+ 실제 오디오·360px/1280px 화면·키보드·접근성·오류 재시도 검증:
|
||
+
|
||
+ ```bash
|
||
+ # Chromium이 없는 개발 환경에서 한 번만 실행합니다.
|
||
+ npx playwright install chromium
|
||
+ npm run test:browser
|
||
+ # 이미 설치된 Chrome을 사용할 때의 대안입니다.
|
||
+ CHROME_PATH=/usr/bin/google-chrome npm run test:browser
|
||
+ ```
|
||
+
|
||
+ Chromium sandbox는 기본으로 켭니다. sandbox를 지원하지 않는 격리된 개발
|
||
+ 환경에서만 `PLAYWRIGHT_NO_SANDBOX=1`을 명시해 끌 수 있습니다. `0`, `false`,
|
||
+ 빈 값이나 미설정은 sandbox를 유지합니다. `CHROME_PATH` 지정은 sandbox를 끄지 않습니다.
|
||
+
|
||
+ 브라우저 테스트는 기존 `dist/`를 사용하므로 소스 변경 후 먼저 빌드하세요.
|
||
+ 실제 음성 재생이 끝나기를 기다려 몇 분이 걸립니다. 로컬 4173 포트를
|
||
+ 테스트 중에만 열고 종료합니다. 스크린샷과 109개 WAV의 query URL·해시·디코드
|
||
+ 결과는 `test-results/`에 저장합니다. 인수 기록은 실행별 새 evidence 경로에
|
||
+ 복사하여 `.agent/evidence-v0.1.1/`의 과거 결과를 보존합니다.
|
||
+
|
||
+ ## 음성과 문서
|
||
+
|
||
+ 한국어 WAV 101개는 직접 쓴 문장을 Microsoft Edge online TTS의
|
||
+ `ko-KR-HyunsuMultilingualNeural`로 v0.1.1에서 생성했으며 WAV 바이트는 그대로 보존했습니다. edge-tts **7.3.1**,
|
||
+ rate `-6%`, pitch `-4Hz`이며 FFmpeg로 **24kHz mono PCM16**으로 변환합니다.
|
||
+ 생성 시 네트워크가 필요하며 앱은 저장된 WAV만 재생합니다. 환경음은 공개 라이선스의 실제 현장 녹음 8개를 각 12초로 변환해 번들합니다. 생성 음성의 독점 권리를 주장하지 않습니다.
|
||
+
|
||
+ intro와 목표 WAV는 모두 `/audio/파일명.wav?v=0.2.3`로 요청합니다.
|
||
+ `src/audio/assets.ts`의 자산 버전 한 곳을 사용하며, 같은 파일명으로 음성을
|
||
+ 교체할 때 이 값을 갱신해 기존 7일 캐시와 구분합니다. 배경은 `/ambience/환경.wav?v=0.2.3`입니다. 제품 버전은 0.2.3입니다.
|
||
+
|
||
+ Linux에서 Python 3.11 이상과 FFmpeg를 준비한 뒤 다음 명령을 사용합니다.
|
||
+ 클라이언트 버전을 고정해도 원격 모델 변경으로 동일 바이트 재생성은 보장하지 않습니다.
|
||
+
|
||
+ ```bash
|
||
+ python3 -m venv .venv-audio
|
||
+ .venv-audio/bin/python -m pip install -r requirements-audio.txt
|
||
+ .venv-audio/bin/python -m pip check
|
||
+ npm run audio:generate
|
||
+ ```
|
||
+
|
||
+ 고정 venv의 Python이 101개 모두 임시 생성·검증하고 디렉터리를 원자 교체합니다.
|
||
+ 요청별 60초 제한과 최대 3회 시도를 적용하며, 실패 시 기존 자산을 보존합니다.
|
||
+ 청취 샘플: [안내](public/audio/intro.wav), [행운의 사과](public/audio/luck-apple.wav).
|
||
+ 생성 방법, 도구 라이선스, 합성 음질의 한계는 [AUDIO_PROVENANCE.md](docs/AUDIO_PROVENANCE.md)를
|
||
+ 참고하세요. 실제 음량은 출력 장치에 따라 달라지며 표기 dB는 디지털 상대값입니다.
|
||
+
|
||
+ 현장음 원본은 `/tmp/findword-ambience-sources`에서만 보관하고 배포하지 않습니다.
|
||
+ `python3 scripts/ambience_audio.py`로 검증된 원본의 파생본과 manifest를 재현합니다.
|
||
+ PD·CC0·CC BY 4.0·CC BY-SA 4.0의 정확한 출처·저작자·변환·해시는
|
||
+ [현장음 manifest](public/ambience/manifest.json), [배포 고지](public/AMBIENCE_NOTICES.md)에 있습니다.
|
||
+ 시장 파생본은 CC BY-SA 4.0을 유지합니다. 외부 링크는 출처 확인용이며 앱은 이를 요청하지 않습니다.
|
||
+
|
||
+ - [변경 이력](CHANGELOG.md)
|
||
+ - [v0.2.3 구현·검증 결과](.agent/RESULT-v0.2.3.md)
|
||
+ - [설계와 상태 전이](docs/ARCHITECTURE.md)
|
||
+ - [Neo를 위한 정적 배포 안내](docs/DEPLOYMENT.md)
|
||
+ - [v0.1.1 RED/GREEN 및 실제 검증 결과](.agent/RESULT-v0.1.1.md)
|
||
+ - [v0.1 역사 기록](.agent/RESULT.md)
|
||
+
|
||
+ 이번 작업에서는 서버 배포와 Git commit/push를 실행하지 않습니다.
|
||
+
|
||
|
||
❯ tests/neural-release.test.ts:73:20
|
||
71| const doc = readFileSync("README.md", "utf8");
|
||
72| expect.soft(doc).toContain(".agent/evidence-v0.2.3/review-fixes/");
|
||
73| expect.soft(doc).toContain("문항별 최대 20점, 라운드 합계 최대 30점");
|
||
| ^
|
||
74| });
|
||
75|
|
||
|
||
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[7/8]⎯
|
||
|
||
|
||
Test Files 2 failed (2)
|
||
Tests 7 failed | 20 passed (27)
|
||
Start at 08:46:34
|
||
Duration 7.76s (tests 81%, environment 12%, setup 4%, transform 2%, import 1%)
|
||
|
||
|
||
EXIT_CODE=1
|