2175 lines
107 KiB
JSON
2175 lines
107 KiB
JSON
{
|
||
"schema_version": "1.1.0",
|
||
"deployed_origin": "https://vignette.chanpaca.net",
|
||
"observed_build": null,
|
||
"deployed_asset": "/assets/index-p7x09Xs2.js",
|
||
"deployed_commit": null,
|
||
"account_roles": {
|
||
"admin": "현재 로그인 확인됨",
|
||
"learner_test": "역할 유효성 검증에는 실제 learner_test 세션 필요",
|
||
"teacher_test": "역할 유효성 검증에는 실제 teacher_test 세션 필요"
|
||
},
|
||
"current_execution_gate": "현재 로그인한 관리자 계정으로 검증 회기 2개와 비식별 가상 대화·리뷰·워크시트 저장이 허용됨. 역할 접근거부 검증은 해당 역할 계정으로 실행하며 관리자 전환을 PASS 대체로 쓰지 않음.",
|
||
"run_id": "production-cu-2026-09-09",
|
||
"method": "computer-use-real-backend",
|
||
"actor_counts": {
|
||
"admin_test": 19,
|
||
"authenticated_role": 3,
|
||
"learner_test": 80,
|
||
"teacher_test": 19,
|
||
"unauthenticated": 7
|
||
},
|
||
"side_effect_counts": {
|
||
"auth_session": 4,
|
||
"none": 106,
|
||
"test_data_mutation": 14,
|
||
"test_data_mutation_requires_owner_approval": 4
|
||
},
|
||
"execution_constraints": [
|
||
"baseline 카탈로그의 모든 scenario는 NOT_RUN과 빈 evidence로 시작한다. 실제 결과는 실행 원장에서만 기록한다.",
|
||
"실행 때 사전조건(계정·테스트 데이터·권한·시간·자연 발생 오류)이 충족되지 않으면 그 실행 시도만 BLOCKED로 기록한다. baseline status를 BLOCKED로 바꾸지 않는다.",
|
||
"mock, page.route, localStorage 인증 조작, API 직접 write는 금지한다.",
|
||
"현재 로그인한 관리자 계정은 비식별 검증 회기 2개와 가상 대화·리뷰·워크시트 저장만 허용한다. 실제 사용자 데이터 수정, 운영 엔진 변경, 자료 공개, 승인 제출, 삭제는 실행하지 않는다.",
|
||
"role 유효성 및 접근거부는 요구된 실제 역할 계정으로 검증한다. admin 계정 또는 공간 전환은 learner_test 접근거부 PASS를 대체하지 않는다.",
|
||
"다른 화면폭 재실행은 같은 ID의 variant로 기록하며 scenario count를 늘리지 않는다.",
|
||
"source에서 확인되지 않은 UI·기능은 존재한다고 가정하지 않는다. 실제 화면에서 확인할 때까지 기능확인필요로 유지하고 PASS로 처리하지 않는다."
|
||
],
|
||
"scenarios": [
|
||
{
|
||
"id": "A01",
|
||
"actor": "unauthenticated",
|
||
"goal": "루트 비로그인 진입",
|
||
"preconditions": "비로그인 새 브라우저 프로필",
|
||
"steps": [
|
||
"CUA의 새 비로그인 브라우저 프로필에서 `https://vignette.chanpaca.net/`를 연다.",
|
||
"주소가 `/login`으로 바뀔 때까지 기다린다.",
|
||
"`로그인` 제목과 `Google 계정으로 로그인` 버튼을 확인한다."
|
||
],
|
||
"expected": "로그인 화면/Google CTA",
|
||
"side_effect": "none",
|
||
"required_data": "비로그인 브라우저 상태; 계정 데이터 불필요",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "A02",
|
||
"actor": "unauthenticated",
|
||
"goal": "학습홈 비로그인 직접주소",
|
||
"preconditions": "비로그인 새 브라우저 프로필",
|
||
"steps": [
|
||
"비로그인 새 프로필에서 `https://vignette.chanpaca.net/learn`를 연다.",
|
||
"`/login`으로 이동한 뒤 로그인 패널의 `Google 계정으로 로그인` 버튼을 확인한다.",
|
||
"학습 대시보드·회기 기록·내담자 목록이 보이지 않는지 확인한다."
|
||
],
|
||
"expected": "로그인으로 안전복귀",
|
||
"side_effect": "none",
|
||
"required_data": "비로그인 브라우저 상태; 계정 데이터 불필요",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "A03",
|
||
"actor": "unauthenticated",
|
||
"goal": "실제 존재 학습회기 deep link 비로그인",
|
||
"preconditions": "비로그인 새 브라우저 프로필; 실제 존재하는 테스트 회기 ID",
|
||
"steps": [
|
||
"비로그인 새 프로필에서 실제 테스트 회기 ID를 넣은 `/learn/session/{테스트회기ID}`를 연다.",
|
||
"`/login`으로 이동한 뒤 `Google 계정으로 로그인` 버튼을 확인한다.",
|
||
"`실시간 상담 축어록`, `학습자 발화 입력`, 회기 내용이 로그인 전 화면에 없는지 확인한다."
|
||
],
|
||
"expected": "내용 미노출 로그인",
|
||
"side_effect": "none",
|
||
"required_data": "실제 존재하는 테스트 회기 ID(비식별); 비로그인 새 브라우저 프로필",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "A04",
|
||
"actor": "unauthenticated",
|
||
"goal": "교수자콘솔 비로그인",
|
||
"preconditions": "비로그인 새 브라우저 프로필",
|
||
"steps": [
|
||
"비로그인 새 프로필에서 `https://vignette.chanpaca.net/teach`를 연다.",
|
||
"`/login`으로 이동한 뒤 로그인 패널을 확인한다.",
|
||
"`교수자 검토 요약`, `학습자 검색`, 학습자 행이 로그인 전 화면에 없는지 확인한다."
|
||
],
|
||
"expected": "학생정보 미노출 로그인",
|
||
"side_effect": "none",
|
||
"required_data": "비로그인 브라우저 상태; 계정 데이터 불필요",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "A05",
|
||
"actor": "unauthenticated",
|
||
"goal": "관리자 비로그인",
|
||
"preconditions": "비로그인 새 브라우저 프로필",
|
||
"steps": [
|
||
"비로그인 새 프로필에서 `https://vignette.chanpaca.net/admin`를 연다.",
|
||
"`/login`으로 이동한 뒤 로그인 패널을 확인한다.",
|
||
"관리자 사이드바의 `운영 홈`, `AI 운영`, `사용자`, `티켓`이 로그인 전 화면에 없는지 확인한다."
|
||
],
|
||
"expected": "운영정보 미노출 로그인",
|
||
"side_effect": "none",
|
||
"required_data": "비로그인 브라우저 상태; 계정 데이터 불필요",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "A06",
|
||
"actor": "unauthenticated",
|
||
"goal": "로그인 키보드만 OAuth 진입",
|
||
"preconditions": "비로그인 새 브라우저 프로필",
|
||
"steps": [
|
||
"비로그인 새 프로필에서 `/login`을 연다.",
|
||
"Tab으로 `Google 계정으로 로그인` 버튼에 가시 포커스를 이동한다.",
|
||
"Enter를 눌러 `accounts.google.com`의 `/v3/signin/accountchooser` 인증 화면을 연다.",
|
||
"계정 선택·제출 전에 중지하고 host와 pathname, `계정을 선택하세요`만 증거로 남긴다."
|
||
],
|
||
"expected": "포커스와 Google 인증화면 정상(계정선택 제출 전 중지 가능)",
|
||
"side_effect": "none",
|
||
"required_data": "비로그인 브라우저 상태; Google 계정 선택·제출 불필요",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "A07",
|
||
"actor": "learner_test",
|
||
"goal": "일반Google 테스트계정 로그인",
|
||
"preconditions": "해당 역할로 인증된 테스트 계정",
|
||
"steps": [
|
||
"`/login`에서 `Google 계정으로 로그인`을 누른다.",
|
||
"소유자가 일반 Google 테스트 계정의 자격증명을 직접 입력하고 인증을 완료한다.",
|
||
"역할 홈(`/learn`, `/teach`, `/admin` 중 해당 경로)에서 사용자 이름과 역할 공간을 확인한다.",
|
||
"`승인된 이메일 도메인 또는 관리자 등록 계정만` 차단 문구가 표시되지 않는지 확인한다."
|
||
],
|
||
"expected": "허용도메인차단없이 자기계정 진입",
|
||
"side_effect": "auth_session",
|
||
"required_data": "소유자가 직접 입력하는 일반 Google 테스트 계정",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "A08",
|
||
"actor": "unauthenticated",
|
||
"goal": "OAuth 취소후 재시도",
|
||
"preconditions": "비로그인 새 브라우저 프로필",
|
||
"steps": [
|
||
"비로그인 상태에서 `/login`의 `Google 계정으로 로그인` 버튼을 누른다.",
|
||
"Google 계정 선택 화면에서 제출하지 않고 브라우저 뒤로가기로 `/login`에 돌아온다.",
|
||
"같은 `Google 계정으로 로그인` 버튼을 다시 활성화한다.",
|
||
"Google 인증 선택 화면이 다시 열리는지 확인한다."
|
||
],
|
||
"expected": "로그인화면 복귀 후 재진입 가능",
|
||
"side_effect": "none",
|
||
"required_data": "비로그인 브라우저 상태; Google 계정 선택·제출 불필요",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "A09",
|
||
"actor": "authenticated_role",
|
||
"goal": "로그인된 사용자의 새탭 진입",
|
||
"preconditions": "비로그인 또는 해당 역할 인증 상태의 브라우저; 실제 사용자 데이터는 읽지 않음",
|
||
"steps": [
|
||
"인증된 테스트 계정이 있는 브라우저에서 새 탭을 연다.",
|
||
"새 탭 주소창에 `https://vignette.chanpaca.net/`를 입력한다.",
|
||
"현재 계정의 역할에 맞는 `/learn`, `/teach`, 또는 `/admin` 경로와 역할용 사이드바를 확인한다."
|
||
],
|
||
"expected": "역할에 맞는 자기 화면",
|
||
"side_effect": "none",
|
||
"required_data": "인증된 테스트 계정; 실제 배포 데이터는 읽기 전용으로 관찰",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "A10",
|
||
"actor": "authenticated_role",
|
||
"goal": "인증상태 새로고침",
|
||
"preconditions": "해당 역할로 인증된 테스트 계정",
|
||
"steps": [
|
||
"인증된 테스트 계정으로 역할 홈을 연다.",
|
||
"브라우저 새로고침을 한 번 실행한다.",
|
||
"`/login`으로 반복 이동하지 않고 같은 역할 홈과 사용자 표시가 다시 나타나는지 확인한다."
|
||
],
|
||
"expected": "로그아웃루프없이 복원",
|
||
"side_effect": "none",
|
||
"required_data": "인증된 테스트 계정; 실제 배포 데이터는 읽기 전용으로 관찰",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "A11",
|
||
"actor": "authenticated_role",
|
||
"goal": "잘못된 앱주소 복귀",
|
||
"preconditions": "기능확인필요",
|
||
"steps": [
|
||
"인증 상태에 맞는 새 탭에서 `/e2e-not-found-20260909`를 연다.",
|
||
"라우터가 안전한 루트로 이동하는 동안 기다린다.",
|
||
"비로그인이면 `/login`과 `Google 계정으로 로그인`, 로그인 상태면 역할 홈을 확인해 앱 탐색을 재개한다."
|
||
],
|
||
"expected": "404/안전한홈 이동으로 사용재개",
|
||
"side_effect": "none",
|
||
"required_data": "잘못된 경로 문자열; 계정 데이터 불필요",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "A12",
|
||
"actor": "learner_test",
|
||
"goal": "로그아웃후 뒤로가기",
|
||
"preconditions": "해당 역할로 인증된 테스트 계정",
|
||
"steps": [
|
||
"소유자가 허용한 폐기 가능 학습자 테스트 계정으로 `/learn`을 연다.",
|
||
"톱바의 `aria-label=로그아웃` 버튼을 누르고 `/login` 이동을 확인한다.",
|
||
"브라우저 뒤로가기를 한 번 실행한다.",
|
||
"`실시간 상담 축어록`, `회기 기록`, `연습 페르소나` 같은 보호 내용이 다시 표시되지 않는지 확인한다."
|
||
],
|
||
"expected": "보호된 내용 재노출없음(테스트계정만)",
|
||
"side_effect": "auth_session",
|
||
"required_data": "소유자가 허용한 폐기 가능 학습자 테스트 계정",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "C01",
|
||
"actor": "learner_test",
|
||
"goal": "학습홈에서 연습으로 이동",
|
||
"preconditions": "인증된 학습자 테스트 계정",
|
||
"steps": [
|
||
"인증된 학습자 테스트 계정으로 `/learn`을 연다.",
|
||
"사이드바의 `학습` 링크를 선택한다.",
|
||
"주소가 `/learn/practice`인지와 `연습할 내담자를 선택합니다.` 제목을 확인한다.",
|
||
"`연습 페르소나` listbox에 실제 서버에서 받은 option 카드가 표시되는지 확인한다."
|
||
],
|
||
"expected": "실서버 사례목록 표시",
|
||
"side_effect": "none",
|
||
"required_data": "인증된 테스트 계정; 실제 배포 데이터는 읽기 전용으로 관찰",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "C02",
|
||
"actor": "learner_test",
|
||
"goal": "제공 사례 선택",
|
||
"preconditions": "인증된 학습자 테스트 계정",
|
||
"steps": [
|
||
"`/learn/practice`의 `연습 페르소나` listbox에서 사용 가능한 option 카드 하나를 선택한다.",
|
||
"선택한 카드의 `aria-selected=true`와 체크 표시를 확인한다.",
|
||
"오른쪽 미리보기의 코드·이름이 선택 카드와 같은지 확인한다.",
|
||
"`주호소` 아래 요약이 선택 카드의 `presenting_summary`와 일치하는지 확인한다."
|
||
],
|
||
"expected": "선택명/미리보기 일치",
|
||
"side_effect": "none",
|
||
"required_data": "인증된 테스트 계정; 실제 배포 데이터는 읽기 전용으로 관찰",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "C03",
|
||
"actor": "learner_test",
|
||
"goal": "사례 상세 주호소 확인",
|
||
"preconditions": "인증된 학습자 테스트 계정",
|
||
"steps": [
|
||
"`연습 페르소나`에서 사용 가능한 테스트 카드를 선택한다.",
|
||
"미리보기의 `주호소` 텍스트를 기록한다.",
|
||
"같은 미리보기에서 `난도`, `접근`, `음성` 값을 별도로 확인한다.",
|
||
"주호소 요약이 난도·접근 값과 섞여 한 필드로 표시되지 않는지 확인한다."
|
||
],
|
||
"expected": "해당사례 주호소로 표면화조건과 혼동없음",
|
||
"side_effect": "none",
|
||
"required_data": "인증된 테스트 계정; 실제 배포 데이터는 읽기 전용으로 관찰",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "C04",
|
||
"actor": "learner_test",
|
||
"goal": "다른사례 전환",
|
||
"preconditions": "인증된 학습자 테스트 계정",
|
||
"steps": [
|
||
"첫 번째 사용 가능한 페르소나 option을 선택하고 미리보기 코드·이름·`주호소`를 기록한다.",
|
||
"다른 코드의 사용 가능한 option을 선택한다.",
|
||
"두 번째 카드만 `aria-selected=true`인지 확인한다.",
|
||
"미리보기 코드·이름·`주호소`와 `연습 기록`의 코드가 두 번째 선택과 일치하고 첫 번째 값이 남지 않는지 확인한다."
|
||
],
|
||
"expected": "이전사례정보잔류없음",
|
||
"side_effect": "none",
|
||
"required_data": "인증된 테스트 계정; 실제 배포 데이터는 읽기 전용으로 관찰",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "C05",
|
||
"actor": "learner_test",
|
||
"goal": "사례별 연습기록 보기",
|
||
"preconditions": "인증된 학습자 테스트 계정",
|
||
"steps": [
|
||
"테스트 이력이 있는 페르소나 option을 선택한다.",
|
||
"`연습 기록` 영역의 `기존 회기` 코드와 회기 수를 확인한다.",
|
||
"각 `회기 기록 목록` 카드의 페르소나 코드가 선택한 카드 코드와 같은지 확인한다.",
|
||
"다른 페르소나를 선택한 뒤 해당 코드의 카드·회기 수로 바뀌는지 확인한다."
|
||
],
|
||
"expected": "선택사례 기록만",
|
||
"side_effect": "none",
|
||
"required_data": "인증된 테스트 계정; 실제 배포 데이터는 읽기 전용으로 관찰",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "C06",
|
||
"actor": "learner_test",
|
||
"goal": "첫연습 사례 안내",
|
||
"preconditions": "인증된 학습자 테스트 계정; 기록 0건인 활성 테스트 페르소나",
|
||
"steps": [
|
||
"기록이 없는 테스트 페르소나 option을 선택한다.",
|
||
"`기존 회기` 수가 0인지와 빈 상태의 `첫 회기를 마치면 실제 저장 기록이 이곳에 쌓입니다.` 안내를 확인한다.",
|
||
"회기 방식의 `완전히 새로 시작`이 선택 가능한지 확인한다.",
|
||
"테스트 회기 생성 권한이 없으면 `완전히 새로 시작`을 누르지 않고 여기서 멈춘다."
|
||
],
|
||
"expected": "기록없는사례 첫회기흐름",
|
||
"side_effect": "none",
|
||
"required_data": "기록 0건인 활성 테스트 페르소나",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "C07",
|
||
"actor": "learner_test",
|
||
"goal": "이력있는사례 이어가기 찾기",
|
||
"preconditions": "인증된 학습자 테스트 계정",
|
||
"steps": [
|
||
"종료 또는 진행 중 이력이 있는 테스트 페르소나 option을 선택한다.",
|
||
"`회기 기록 목록`에서 진행 중 카드의 `이어하기`, 종료 카드의 `다음 회기 이어가기`, 리뷰 가능 카드의 `리뷰` 또는 `기록` 조작을 구분해 확인한다.",
|
||
"`회기 연속성` 영역이 표시되면 `이어서 진행` 라디오와 `이어서 진행할 사례` 선택 상자의 사용 가능 상태를 확인한다.",
|
||
"새 회기를 만들지 않고 기존 회기와 다음 회기 조작이 구분되는지만 기록한다."
|
||
],
|
||
"expected": "기존회기/새회기 구분",
|
||
"side_effect": "none",
|
||
"required_data": "인증된 테스트 계정; 실제 배포 데이터는 읽기 전용으로 관찰",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "C08",
|
||
"actor": "learner_test",
|
||
"goal": "사용불가사례 선택시도",
|
||
"preconditions": "인증된 학습자 테스트 계정; 사용 불가 상태의 사전등록 테스트 페르소나",
|
||
"steps": [
|
||
"사용 불가 상태의 사전등록 테스트 페르소나가 목록에 있는지 확인한다.",
|
||
"해당 option의 `aria-disabled=true`, 비활성화 상태, `사용 불가` 배지를 확인한다.",
|
||
"비활성 카드에는 클릭으로 선택 상태가 생기지 않는지 확인한다.",
|
||
"미리보기의 `사용 가능한 내담자가 없습니다.` 또는 카탈로그 차단 안내와 시작 버튼 비활성 조건을 확인한다."
|
||
],
|
||
"expected": "시작차단과 이유",
|
||
"side_effect": "none",
|
||
"required_data": "사용 불가 상태의 사전등록 테스트 페르소나",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "C09",
|
||
"actor": "learner_test",
|
||
"goal": "존재하지않는 사례 직접주소",
|
||
"preconditions": "인증된 학습자 테스트 계정",
|
||
"steps": [
|
||
"인증된 학습자 테스트 계정으로 `/learn/session/존재하지않는사례코드`를 연다.",
|
||
"화면이 다른 실제 페르소나의 회기 준비·축어록으로 바뀌지 않는지 확인한다.",
|
||
"표시되는 오류·안전 복귀·로그인 화면 중 실제 결과의 URL과 문구를 기록한다."
|
||
],
|
||
"expected": "다른사례로 몰래시작안함",
|
||
"side_effect": "none",
|
||
"required_data": "인증된 테스트 계정; 실제 배포 데이터는 읽기 전용으로 관찰",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "C10",
|
||
"actor": "learner_test",
|
||
"goal": "추천사례에서 시작준비",
|
||
"preconditions": "인증된 학습자 테스트 계정",
|
||
"steps": [
|
||
"인증된 학습자 테스트 계정으로 `/learn`을 연다.",
|
||
"`다음 연습 추천` 패널의 권장 문구와 `연습 시작하기` 또는 `리뷰 확인하기` 버튼을 확인한다.",
|
||
"`연습 시작하기`가 있을 때 누르고 `/learn/practice`로 이동한다.",
|
||
"이동한 미리보기 코드·이름이 추천에서 가리킨 대상과 같은지 확인하고 회기 생성 버튼은 누르지 않는다."
|
||
],
|
||
"expected": "추천대상과 준비대상일치",
|
||
"side_effect": "none",
|
||
"required_data": "인증된 테스트 계정; 실제 배포 데이터는 읽기 전용으로 관찰",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "C11",
|
||
"actor": "learner_test",
|
||
"goal": "사례선택 키보드조작",
|
||
"preconditions": "인증된 학습자 테스트 계정",
|
||
"steps": [
|
||
"`/learn/practice`에서 Tab으로 `연습 페르소나`의 option 카드에 포커스를 이동한다.",
|
||
"Enter 또는 Space로 사용 가능한 option을 선택한다.",
|
||
"선택 카드의 `aria-selected=true`, 미리보기 변경, `완전히 새로 시작` 또는 `진행 중인 회기 이어가기` 버튼의 사용 가능 상태를 확인한다."
|
||
],
|
||
"expected": "포커스/선택/준비가능",
|
||
"side_effect": "none",
|
||
"required_data": "인증된 테스트 계정; 실제 배포 데이터는 읽기 전용으로 관찰",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "C12",
|
||
"actor": "learner_test",
|
||
"goal": "모바일 사례탐색",
|
||
"preconditions": "인증된 학습자 테스트 계정",
|
||
"steps": [
|
||
"브라우저 폭을 390px variant로 설정하고 인증된 학습자 테스트 계정으로 `/learn/practice`를 연다.",
|
||
"`연습 페르소나`에서 사용 가능한 option을 선택한다.",
|
||
"미리보기의 `주호소`, `난도`, `접근`, 회기 방식, 시작 버튼까지 스크롤해 접근한다.",
|
||
"가로 스크롤 없이 모든 조작과 텍스트가 보이는지 확인하고 시작 버튼은 누르지 않는다."
|
||
],
|
||
"expected": "선택/상세/준비 끝까지 사용가능",
|
||
"side_effect": "none",
|
||
"required_data": "인증된 테스트 계정; 실제 배포 데이터는 읽기 전용으로 관찰",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "C13",
|
||
"actor": "learner_test",
|
||
"goal": "상세닫고 목록복귀",
|
||
"preconditions": "인증된 학습자 테스트 계정; 기능확인필요",
|
||
"steps": [
|
||
"`/learn/practice`에서 사용 가능한 option을 선택해 오른쪽 미리보기를 연다.",
|
||
"소스에는 별도 상세 닫기 조작이 확인되지 않았으므로, 실제 배포 화면에 닫기 조작이 나타날 때만 그 정확한 라벨을 기록한다.",
|
||
"닫기 조작이 있으면 실행 뒤 `연습 페르소나` listbox와 기존 `aria-selected` 선택이 유지되는지 확인한다.",
|
||
"닫기 조작이 없으면 `기능확인필요`로 기록하고 존재하지 않는 버튼을 추정해 누르지 않는다."
|
||
],
|
||
"expected": "선택맥락유지",
|
||
"side_effect": "none",
|
||
"required_data": "인증된 테스트 계정; 실제 배포 데이터는 읽기 전용으로 관찰",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "C14",
|
||
"actor": "learner_test",
|
||
"goal": "시작전 이론모드 선택",
|
||
"preconditions": "인증된 학습자 테스트 계정; 소유자 허용 뒤 테스트 전용 계정·페르소나",
|
||
"steps": [
|
||
"소유자가 허용한 테스트 전용 계정·페르소나를 선택한다.",
|
||
"회기 방식과 `완전히 새로 시작`을 확인한 뒤 테스트 회기 생성이 허용된 경우에만 시작한다.",
|
||
"회기 시작 전 준비 화면의 `이론모드 선택` fieldset에서 원하는 이론 버튼을 선택한다.",
|
||
"선택 상태가 준비 화면에 반영되는지 확인하고 실제 학습자 발화는 보내지 않는다."
|
||
],
|
||
"expected": "준비화면에선택반영",
|
||
"side_effect": "test_data_mutation_requires_owner_approval",
|
||
"required_data": "소유자 허용 뒤 테스트 전용 계정·페르소나",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "C15",
|
||
"actor": "learner_test",
|
||
"goal": "새등록 테스트페르소나 선택",
|
||
"preconditions": "인증된 학습자 테스트 계정; 사전등록된 새 테스트 페르소나",
|
||
"steps": [
|
||
"사전등록된 새 테스트 페르소나의 code를 가진 option을 `연습 페르소나`에서 선택한다.",
|
||
"미리보기 코드·이름·`주호소`, `난도`, `접근`, `음성`을 확인한다.",
|
||
"`완전히 새로 시작` 버튼이 사용 가능한지 확인한다.",
|
||
"회기 생성 허용이 없으면 버튼을 누르지 않고 내담자 정보와 준비 진입 조건만 기록한다."
|
||
],
|
||
"expected": "내담자정보/상담준비 정상",
|
||
"side_effect": "none",
|
||
"required_data": "사전등록된 새 테스트 페르소나",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "C16",
|
||
"actor": "learner_test",
|
||
"goal": "퇴역테스트페르소나 deep link",
|
||
"preconditions": "인증된 학습자 테스트 계정; 퇴역 상태 테스트 페르소나 ID; 기능확인필요",
|
||
"steps": [
|
||
"퇴역 상태의 사전등록 테스트 페르소나 code로 `/learn/session/{퇴역테스트페르소나ID}`를 연다.",
|
||
"다른 활성 페르소나의 회기 준비·축어록이 자동으로 열리지 않는지 확인한다.",
|
||
"화면에 나타난 차단·오류·안전 복귀 문구와 URL을 기록하고 신규 회기 시작 조작을 실행하지 않는다."
|
||
],
|
||
"expected": "신규회기 차단",
|
||
"side_effect": "none",
|
||
"required_data": "퇴역 상태 테스트 페르소나 ID",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "C17",
|
||
"actor": "learner_test",
|
||
"goal": "두사례간 이력카운트대조",
|
||
"preconditions": "인증된 학습자 테스트 계정",
|
||
"steps": [
|
||
"테스트 이력이 있는 첫 번째 페르소나 option을 선택한다.",
|
||
"`기존 회기` 수와 `회기 기록 목록` 카드의 code·턴 수를 기록한다.",
|
||
"두 번째 테스트 페르소나 option을 선택하고 같은 값을 기록한다.",
|
||
"각 목록 카드가 현재 선택 code만 가지며 두 대상의 수·카드가 섞이지 않는지 확인한다."
|
||
],
|
||
"expected": "각기록 혼합없음",
|
||
"side_effect": "none",
|
||
"required_data": "인증된 테스트 계정; 실제 배포 데이터는 읽기 전용으로 관찰",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "C18",
|
||
"actor": "learner_test",
|
||
"goal": "연습주소 새로고침",
|
||
"preconditions": "인증된 학습자 테스트 계정",
|
||
"steps": [
|
||
"인증된 학습자 테스트 계정으로 `/learn/practice`를 연다.",
|
||
"사용 가능한 option을 선택해 `aria-selected=true`와 미리보기 code를 확인한다.",
|
||
"브라우저 새로고침을 한 번 실행한다.",
|
||
"목록 로딩 뒤 선택 option·미리보기·시작 버튼이 유효한 실제 카탈로그 상태인지 확인한다."
|
||
],
|
||
"expected": "사례목록과 선택유효성 정상",
|
||
"side_effect": "none",
|
||
"required_data": "인증된 테스트 계정; 실제 배포 데이터는 읽기 전용으로 관찰",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "S01",
|
||
"actor": "learner_test",
|
||
"goal": "시작전 안내확인",
|
||
"preconditions": "learner_test로 로그인한 실제 브라우저 세션; 실제 배포본 https://vignette.chanpaca.net; 시작하지 않은 테스트 전용 비식별 사례",
|
||
"steps": [
|
||
"`/learn/practice`에서 테스트 전용 페르소나 option을 선택하고 `완전히 새로 시작`을 누른다.",
|
||
"`회기 시작 전 준비`의 `이번 회기 목표 선택`에서 목표 하나를 골라 첫 발화 기준을 확인한다.",
|
||
"`회기 시작`을 눌러 실제 회기 작업면을 연다.",
|
||
"`첫 발화 전에 내 기준을 잠급니다`에서 `목표`, `과업`, `유대` 각 fieldset의 radio를 하나씩 선택한다.",
|
||
"`기준 잠그고 첫 발화 준비`을 누른다.",
|
||
"`학습자 발화 입력`이 열리고 첫 발화 전 기준이 잠겼다는 상태를 확인한다."
|
||
],
|
||
"expected": "대화전 준비상태명확",
|
||
"side_effect": "none",
|
||
"required_data": "시작 전 상태의 테스트 전용 비식별 사례",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "S02",
|
||
"actor": "learner_test",
|
||
"goal": "테스트회기1개 시작",
|
||
"preconditions": "learner_test로 로그인한 실제 브라우저 세션; 실제 배포본; 진행 중 회기가 없는 테스트 전용 비식별 사례",
|
||
"steps": [
|
||
"`/learn/practice`에서 비식별 테스트 페르소나를 선택하고 `완전히 새로 시작`을 누른다.",
|
||
"`회기 시작 전 준비`의 `이번 회기 목표 선택`에서 목표 하나를 고른다.",
|
||
"`회기 시작`을 눌러 새 테스트 회기를 만든다.",
|
||
"`첫 발화 전에 내 기준을 잠급니다`에서 `목표`, `과업`, `유대`의 radio를 각각 하나씩 선택한다.",
|
||
"`기준 잠그고 첫 발화 준비`을 눌러 회기 전 판단을 잠근다.",
|
||
"표시된 페르소나 코드와 회기 URL의 식별값, `학습자 발화 입력`이 같은 새 회기임을 확인한다."
|
||
],
|
||
"expected": "사례/회기 식별일치",
|
||
"side_effect": "test_data_mutation",
|
||
"required_data": "소유자 허용을 받은 미사용 테스트 계정과 비식별 사례",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "S03",
|
||
"actor": "learner_test",
|
||
"goal": "무입력전송",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; 응답 생성 중이 아닌 활성 테스트 회기",
|
||
"steps": [
|
||
"/learn/session/{테스트회기ID}에서 ‘학습자 발화 입력’의 현재 축어록 턴 수를 기록한다.",
|
||
"입력란을 비운 채 Enter를 누른다.",
|
||
"입력란과 ‘실시간 상담 축어록’을 다시 확인한다."
|
||
],
|
||
"expected": "서버턴생성안함",
|
||
"side_effect": "none",
|
||
"required_data": "활성 테스트 회기와 전송 전 턴 수",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "S04",
|
||
"actor": "learner_test",
|
||
"goal": "공백만전송",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; 응답 생성 중이 아닌 활성 테스트 회기",
|
||
"steps": [
|
||
"‘학습자 발화 입력’에 공백만 입력하고 현재 턴 수를 기록한다.",
|
||
"Enter를 누른다.",
|
||
"공백이 새 학습자 발화나 내담자 응답으로 추가되지 않았는지 확인한다."
|
||
],
|
||
"expected": "동일차단",
|
||
"side_effect": "none",
|
||
"required_data": "활성 테스트 회기",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "S05",
|
||
"actor": "learner_test",
|
||
"goal": "한국어 첫발화전송",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; 새 테스트 전용 비식별 회기",
|
||
"steps": [
|
||
"‘학습자 발화 입력’에 ‘실습용 가상 사례에서 오늘의 기분을 한 문장으로 정리해 보고 싶어요.’를 입력한다.",
|
||
"Enter를 한 번 누른다.",
|
||
"축어록에 학습자 발화가 먼저 나타나고 실제 내담자 응답이 뒤따르는지 확인한다."
|
||
],
|
||
"expected": "실제내담자응답 수신",
|
||
"side_effect": "test_data_mutation",
|
||
"required_data": "소유자 허용을 받은 새 테스트 회기와 비개인정보 한국어 입력",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "S06",
|
||
"actor": "learner_test",
|
||
"goal": "두번째맥락발화",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; S05 뒤 내담자 응답이 완료된 동일 테스트 회기",
|
||
"steps": [
|
||
"첫 왕복이 끝난 뒤 ‘학습자 발화 입력’에 ‘방금 말한 감정을 더 천천히 살펴보고 싶어요.’를 입력한다.",
|
||
"Enter를 한 번 누른다.",
|
||
"축어록의 새 두 턴이 기존 회기 아래에 이어지고 주소의 회기 ID가 바뀌지 않는지 확인한다."
|
||
],
|
||
"expected": "같은회기 이어짐",
|
||
"side_effect": "test_data_mutation",
|
||
"required_data": "비개인정보 두 번째 한국어 입력과 기존 테스트 회기",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "S07",
|
||
"actor": "learner_test",
|
||
"goal": "ShiftEnter 여러줄작성",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; 활성 테스트 회기",
|
||
"steps": [
|
||
"‘학습자 발화 입력’에 ‘실습용 첫 줄’을 입력한다.",
|
||
"Shift+Enter를 누르고 ‘실습용 둘째 줄’을 입력한다.",
|
||
"입력란에 두 줄이 유지되고 축어록에 새 턴이 생기지 않았는지 확인한 뒤 입력을 지운다."
|
||
],
|
||
"expected": "전송전 줄바꿈보존",
|
||
"side_effect": "none",
|
||
"required_data": "활성 테스트 회기",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "S08",
|
||
"actor": "learner_test",
|
||
"goal": "Enter전송",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; 응답 생성 중이 아닌 활성 테스트 회기",
|
||
"steps": [
|
||
"‘학습자 발화 입력’에 ‘실습용 가상 문장입니다. 다음 단계를 확인하고 싶어요.’를 입력한다.",
|
||
"Enter를 한 번 누른다.",
|
||
"입력란이 비고 축어록에 해당 학습자 발화가 정확히 한 번 나타나는지 확인한다.",
|
||
"내담자 응답 완료 뒤에도 같은 문장이 중복되지 않는지 확인한다."
|
||
],
|
||
"expected": "1회전송",
|
||
"side_effect": "test_data_mutation",
|
||
"required_data": "비개인정보 한국어 입력과 테스트 회기",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "S09",
|
||
"actor": "learner_test",
|
||
"goal": "빠른중복전송",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; 응답 생성 중이 아닌 활성 테스트 회기",
|
||
"steps": [
|
||
"‘학습자 발화 입력’에 ‘실습용 중복 방지 확인 문장입니다.’를 입력한다.",
|
||
"Enter를 빠르게 두 번 누른다.",
|
||
"축어록에서 해당 학습자 문장이 한 번만 추가되고 내담자 응답이 한 번만 시작되는지 확인한다."
|
||
],
|
||
"expected": "중복학습자턴없음",
|
||
"side_effect": "test_data_mutation",
|
||
"required_data": "비개인정보 한국어 입력과 테스트 회기",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "S10",
|
||
"actor": "learner_test",
|
||
"goal": "응답중 다음초안작성",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; 자연 발생한 내담자 응답 생성 중인 테스트 회기",
|
||
"steps": [
|
||
"내담자 응답이 축어록에 진행 중인 상태인지 확인한다.",
|
||
"‘학습자 발화 입력’에 ‘실습용 다음 초안이며 아직 보내지 않습니다.’를 입력한다.",
|
||
"내담자 응답이 끝난 뒤 입력란에 초안이 남아 있고 축어록에는 새 학습자 턴이 없는지 확인한다."
|
||
],
|
||
"expected": "초안보존/실전송대기",
|
||
"side_effect": "none",
|
||
"required_data": "응답 생성 중 상태가 자연 발생한 테스트 회기",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "S11",
|
||
"actor": "learner_test",
|
||
"goal": "긴정상길이발화",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; 응답 생성 중이 아닌 테스트 회기",
|
||
"steps": [
|
||
"사전 준비한 비개인정보 한국어 긴 문장(제품이 허용하는 길이)을 ‘학습자 발화 입력’에 붙여 넣는다.",
|
||
"Enter를 한 번 누른다.",
|
||
"학습자 발화와 내담자 응답의 줄바꿈·문장 끝이 보이고 가로 스크롤이 생기지 않는지 확인한다."
|
||
],
|
||
"expected": "잘림/가로넘침없이수신",
|
||
"side_effect": "test_data_mutation",
|
||
"required_data": "제품 허용 길이 안의 비개인정보 긴 한국어 테스트 문자열",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "S12",
|
||
"actor": "learner_test",
|
||
"goal": "허용길이초과입력",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; 운영에 전송하지 않아도 되는 테스트 회기; 제품 문자 한도 근거",
|
||
"steps": [
|
||
"현재 Session 소스에는 ‘학습자 발화 입력’의 길이 제한이나 초과 차단 문구가 없음을 확인한다.",
|
||
"운영 LLM 전송 없이 검증할 수 있는 사전 설정 한도 데이터가 있는지 확인한다.",
|
||
"그 데이터가 없으면 긴 문자열을 제출하지 않고 BLOCKED로 기록한다."
|
||
],
|
||
"expected": "UI차단/명확한제한(실LLM과다전송금지)",
|
||
"side_effect": "none",
|
||
"required_data": "프런트 또는 서버의 확인된 문자 한도와 비전송 검증 환경",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "S13",
|
||
"actor": "learner_test",
|
||
"goal": "한영숫자기호혼합",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; 응답 생성 중이 아닌 테스트 회기",
|
||
"steps": [
|
||
"‘학습자 발화 입력’에 ‘실습용 Mix A/B 42! #확인?’을 입력한다.",
|
||
"Enter를 한 번 누른다.",
|
||
"축어록의 학습자 턴에서 한글·영문·숫자·기호가 같은 순서로 보이는지 확인한다."
|
||
],
|
||
"expected": "깨짐없이표시",
|
||
"side_effect": "test_data_mutation",
|
||
"required_data": "비개인정보 혼합 문자열과 테스트 회기",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "S14",
|
||
"actor": "learner_test",
|
||
"goal": "위로스크롤하며대화읽기",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; 여러 턴이 있는 테스트 회기",
|
||
"steps": [
|
||
"‘실시간 상담 축어록’을 위로 스크롤해 과거 발화를 읽는다.",
|
||
"현재 스크롤 위치와 보이는 과거 발화를 확인한다.",
|
||
"자동으로 맨 아래로 이동하지 않는지 확인한다."
|
||
],
|
||
"expected": "자동하단강제이동없음",
|
||
"side_effect": "none",
|
||
"required_data": "여러 턴이 저장된 테스트 회기",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "S15",
|
||
"actor": "learner_test",
|
||
"goal": "최신으로복귀",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; 위로 스크롤한 여러 턴 테스트 회기",
|
||
"steps": [
|
||
"축어록을 위로 스크롤해 ‘최신으로’ 버튼을 표시한다.",
|
||
"‘최신으로’를 클릭한다.",
|
||
"마지막 축어록 턴이 보이고 ‘최신으로’ 버튼이 사라지는지 확인한다."
|
||
],
|
||
"expected": "마지막턴으로돌아감",
|
||
"side_effect": "none",
|
||
"required_data": "여러 턴이 저장된 테스트 회기",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "S16",
|
||
"actor": "learner_test",
|
||
"goal": "도움말 열고닫기",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; 활성 테스트 회기",
|
||
"steps": [
|
||
"‘학습자 발화 입력’에 전송하지 않을 ‘실습용 초안 보존 확인’ 문장을 입력한다.",
|
||
"? 또는 Ctrl+/를 눌러 ‘키보드 단축키 안내’ 대화상자를 연다.",
|
||
"Esc 또는 ‘확인 (Esc)’로 닫는다.",
|
||
"입력란의 초안과 기존 축어록이 그대로인지 확인한다."
|
||
],
|
||
"expected": "작성문/대화유지",
|
||
"side_effect": "none",
|
||
"required_data": "활성 테스트 회기",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "S17",
|
||
"actor": "learner_test",
|
||
"goal": "일시정지후재개",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; 응답 생성 중이 아닌 활성 테스트 회기",
|
||
"steps": [
|
||
"‘일시정지’를 클릭한다.",
|
||
"‘학습자 발화 입력’의 안내가 ‘일시정지 중입니다.’이고 입력이 막혔는지 확인한다.",
|
||
"‘이어가기’를 클릭한다.",
|
||
"입력란이 다시 활성화되고 상단 경과 표기가 일관되게 이어지는지 확인한다."
|
||
],
|
||
"expected": "입력상태/시간흐름일관",
|
||
"side_effect": "none",
|
||
"required_data": "활성 테스트 회기",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "S18",
|
||
"actor": "learner_test",
|
||
"goal": "회기설정열고취소",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; 활성 테스트 회기",
|
||
"steps": [
|
||
"현재 Session 소스에서 활성 회기 중 ‘회기 설정’ 열기·취소 조작이 제공되는지 확인한다.",
|
||
"확인된 활성 회기 설정 제어가 없으면 임의의 패널을 설정으로 간주하지 않는다.",
|
||
"발화·초안 보존을 검증하지 않고 BLOCKED로 기록한다."
|
||
],
|
||
"expected": "발화/초안유지",
|
||
"side_effect": "none",
|
||
"required_data": "활성 회기 설정 제어의 실제 배포 증거",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "S19",
|
||
"actor": "learner_test",
|
||
"goal": "회기 새로고침",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; 저장된 여러 턴이 있는 테스트 회기",
|
||
"steps": [
|
||
"축어록의 학습자·내담자 턴 수와 마지막 문장을 기록한다.",
|
||
"브라우저 새로고침을 수행한다.",
|
||
"동일 /learn/session/{테스트회기ID}에서 기존 턴과 마지막 문장이 복원되고 중복 턴이 없는지 확인한다."
|
||
],
|
||
"expected": "저장된턴복원/중복없음",
|
||
"side_effect": "none",
|
||
"required_data": "저장 완료된 여러 턴 테스트 회기",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "S20",
|
||
"actor": "learner_test",
|
||
"goal": "다른화면후이어가기",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; 저장된 턴이 있는 활성 테스트 회기",
|
||
"steps": [
|
||
"상단 ‘기록으로’를 클릭해 /learn/history로 이동한다.",
|
||
"브라우저 뒤로 가기로 원래 /learn/session/{테스트회기ID}로 돌아온다.",
|
||
"상단의 ‘이전 회기 기록을 불러왔습니다.’ 또는 저장된 축어록을 확인하고 같은 회기 ID인지 대조한다."
|
||
],
|
||
"expected": "같은회기복원",
|
||
"side_effect": "none",
|
||
"required_data": "저장된 턴이 있는 활성 테스트 회기",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "S21",
|
||
"actor": "learner_test",
|
||
"goal": "정상종료확인",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; 종료 가능한 테스트 전용 비식별 회기",
|
||
"steps": [
|
||
"활성 회기에서 ‘종료하고 리뷰 보기’를 클릭한다.",
|
||
"‘회기를 종료할까요?’ 대화상자의 저장·리뷰 이동 안내를 확인한다.",
|
||
"대화상자의 ‘종료하고 리뷰 보기’를 한 번 클릭한다.",
|
||
"종료 상태와 /learn/session/{테스트회기ID}/review 이동을 확인한다."
|
||
],
|
||
"expected": "종료저장/리뷰이동",
|
||
"side_effect": "test_data_mutation",
|
||
"required_data": "소유자 허용을 받은 종료 대상 테스트 회기",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "S22",
|
||
"actor": "learner_test",
|
||
"goal": "종료취소",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; 활성 테스트 회기",
|
||
"steps": [
|
||
"‘종료하고 리뷰 보기’를 클릭해 ‘회기를 종료할까요?’ 대화상자를 연다.",
|
||
"‘계속 진행’을 클릭한다.",
|
||
"입력란이 ‘종료된 회기입니다.’ 상태가 아니고 기존 축어록이 유지되는지 확인한다."
|
||
],
|
||
"expected": "진행상태유지",
|
||
"side_effect": "none",
|
||
"required_data": "활성 테스트 회기",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "S23",
|
||
"actor": "learner_test",
|
||
"goal": "실제응답실패시복구",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; 자연 발생한 내담자 응답 실패가 기록된 테스트 전용 회기",
|
||
"steps": [
|
||
"자연 발생한 실패 배너와 ‘다시 전송’ 버튼이 보이는 회기인지 확인한다.",
|
||
"실패 전 입력한 비개인정보 발화가 복원됐는지 확인한다.",
|
||
"자연 실패 데이터가 없으면 장애를 유발하지 않고 BLOCKED로 기록한다."
|
||
],
|
||
"expected": "초안복원/재전송/부분턴오염없음(실패미관찰이면BLOCKED,고의운영장애금지)",
|
||
"side_effect": "none",
|
||
"required_data": "자연 발생 응답 실패와 비개인정보 발화가 남은 테스트 회기",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "S24",
|
||
"actor": "learner_test",
|
||
"goal": "발화없이종료한별도테스트회기",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; 발화가 없는 별도 테스트 전용 회기",
|
||
"steps": [
|
||
"축어록에 학습자·내담자 발화가 없는 새 테스트 회기인지 확인한다.",
|
||
"‘종료하고 리뷰 보기’를 열고 대화상자의 같은 버튼으로 종료를 확정한다.",
|
||
"리뷰에서 ‘축어록 없음’과 종료 회기 ID를 확인한다.",
|
||
"테스트 계정의 완료 수와 성취 배지가 늘지 않았는지 확인한다."
|
||
],
|
||
"expected": "완료수와성취배지증가없음(추가생성필요)",
|
||
"side_effect": "test_data_mutation",
|
||
"required_data": "소유자 허용을 받은 발화 없는 별도 테스트 회기와 종료 전 계정 상태",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "R01",
|
||
"actor": "learner_test",
|
||
"goal": "종료리뷰열기",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; 종료된 테스트 전용 회기",
|
||
"steps": [
|
||
"/learn/session/{테스트회기ID}/review를 연다.",
|
||
"‘리뷰 생성 상태’와 화면 주소의 회기 ID를 확인한다.",
|
||
"표시된 사례 정보가 종료 전 회기와 같은지 확인한다."
|
||
],
|
||
"expected": "해당사례/회기일치",
|
||
"side_effect": "none",
|
||
"required_data": "종료된 테스트 전용 회기",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "R02",
|
||
"actor": "learner_test",
|
||
"goal": "축어록읽기",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; 학습자·내담자 턴이 저장된 종료 테스트 회기",
|
||
"steps": [
|
||
"리뷰의 ‘축어록’ 탭을 클릭한다.",
|
||
"‘전체’를 선택해 저장된 턴의 화자와 순서를 읽는다.",
|
||
"‘내 발화만’을 눌러 학습자 턴만 남는지 확인한 뒤 ‘전체’로 되돌린다."
|
||
],
|
||
"expected": "실제보낸턴/응답순서보존",
|
||
"side_effect": "none",
|
||
"required_data": "순서를 알고 있는 저장 완료 테스트 축어록",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "R03",
|
||
"actor": "learner_test",
|
||
"goal": "리뷰새로고침",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; 저장된 축어록과 리뷰 데이터가 있는 종료 테스트 회기",
|
||
"steps": [
|
||
"‘축어록’ 탭에서 턴 수와 한 개의 비개인정보 문장을 기록한다.",
|
||
"브라우저를 새로고침한다.",
|
||
"동일 리뷰 주소에서 같은 탭을 열어 기록한 턴과 문장이 유지되는지 확인한다."
|
||
],
|
||
"expected": "내용지속",
|
||
"side_effect": "none",
|
||
"required_data": "저장 완료된 종료 테스트 회기",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "R04",
|
||
"actor": "learner_test",
|
||
"goal": "피드백탭",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; 리뷰 생성 상태가 알려진 종료 테스트 회기",
|
||
"steps": [
|
||
"‘피드백’ 탭을 클릭한다.",
|
||
"‘리뷰 생성 상태’의 완료·대기·실패 표시를 읽는다.",
|
||
"상태에 맞춰 ‘감정 타임라인 대기’, ‘평가 대기’, 또는 생성된 피드백 카드가 표시되는지 확인한다."
|
||
],
|
||
"expected": "완료/대기/실패상태구분",
|
||
"side_effect": "none",
|
||
"required_data": "평가 상태가 확인된 종료 테스트 회기",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "R05",
|
||
"actor": "learner_test",
|
||
"goal": "자기예측이유공란제출",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; 예측 revision이 없는 종료 테스트 회기",
|
||
"steps": [
|
||
"‘피드백’ 탭에서 ‘첫 자기예측 기록’을 찾는다.",
|
||
"‘성공 가능성’과 ‘이 예측에 대한 확신’을 조절하되 ‘그렇게 예상한 이유’는 비워 둔다.",
|
||
"‘첫 예측 기록’ 버튼이 비활성화되어 새 revision이 만들어지지 않는지 확인한다."
|
||
],
|
||
"expected": "검증오류/기록생성없음",
|
||
"side_effect": "none",
|
||
"required_data": "예측 revision이 없는 종료 테스트 회기",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "R06",
|
||
"actor": "learner_test",
|
||
"goal": "자기예측정상저장",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; 예측 revision이 없는 종료 테스트 회기",
|
||
"steps": [
|
||
"‘피드백’ 탭에서 ‘성공 가능성’과 ‘이 예측에 대한 확신’을 선택한다.",
|
||
"‘그렇게 예상한 이유’에 ‘비개인정보 실습 판단: 질문 뒤 감정을 요약하는 반응을 유지할 수 있습니다.’를 입력한다.",
|
||
"‘첫 예측 기록’을 한 번 클릭한다.",
|
||
"‘예측 revision을 기록했어. 외부평가 공개 전 잠금을 완료해줘.’ 상태 메시지를 확인한다."
|
||
],
|
||
"expected": "점수/이유1회저장",
|
||
"side_effect": "test_data_mutation",
|
||
"required_data": "소유자 허용을 받은 미기록 종료 테스트 회기와 비개인정보 판단 이유",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "R07",
|
||
"actor": "learner_test",
|
||
"goal": "잠그기전수정",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; 잠기지 않은 첫 예측이 있는 종료 테스트 회기",
|
||
"steps": [
|
||
"‘피드백’ 탭에서 ‘성공 가능성’을 다른 5% 단위 값으로 바꾼다.",
|
||
"‘그렇게 예상한 이유’에 ‘비개인정보 실습 판단: 이전 판단을 더 보수적으로 조정합니다.’를 입력한다.",
|
||
"‘예측 수정 기록’을 한 번 클릭하고 새 revision 상태 메시지를 확인한다."
|
||
],
|
||
"expected": "개정반영",
|
||
"side_effect": "test_data_mutation",
|
||
"required_data": "소유자 허용을 받은 잠기지 않은 예측과 비개인정보 판단 이유",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "R08",
|
||
"actor": "learner_test",
|
||
"goal": "자기예측명시잠금",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; 잠기지 않은 최신 예측 revision이 있는 종료 테스트 회기",
|
||
"steps": [
|
||
"‘명시적 잠금’의 ‘잠근 뒤 수정할 수 없음을 확인했어’ 체크박스를 선택한다.",
|
||
"활성화된 ‘이 예측 잠그기’를 한 번 클릭한다.",
|
||
"‘잠근 예측은 수정할 수 없어’와 ‘독립 수행 관찰’ 표시를 확인한다.",
|
||
"잠금 버튼이 다시 쓰기 동작을 만들지 않는지 확인한다."
|
||
],
|
||
"expected": "잠금상태/중복잠금없음",
|
||
"side_effect": "test_data_mutation",
|
||
"required_data": "소유자 허용을 받은 잠기지 않은 예측 revision",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "R09",
|
||
"actor": "learner_test",
|
||
"goal": "잠금후새로고침",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; R08에서 잠긴 예측이 있는 종료 테스트 회기",
|
||
"steps": [
|
||
"‘피드백’ 탭의 잠금 표시를 확인한다.",
|
||
"브라우저를 새로고침한다.",
|
||
"다시 ‘피드백’ 탭을 열어 ‘예측 수정 기록’ 입력 폼이 없고 잠금 상태가 유지되는지 확인한다."
|
||
],
|
||
"expected": "수정금지유지",
|
||
"side_effect": "none",
|
||
"required_data": "잠긴 예측이 저장된 종료 테스트 회기",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "R10",
|
||
"actor": "learner_test",
|
||
"goal": "외부평가공개순서",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; 같은 조건의 잠기지 않은 회기와 잠긴 회기 각 1개",
|
||
"steps": [
|
||
"잠기지 않은 회기의 ‘피드백’ 탭에서 ‘아직 공개하지 않음’ 또는 ‘예측을 잠가야 비교 가능’을 확인한다.",
|
||
"잠긴 회기의 같은 카드를 열어 ‘독립 수행 관찰’과 허용된 평가 범위만 표시되는지 확인한다.",
|
||
"두 회기에서 실제 진단·인구집단 주장이 표시되지 않는지 확인한다."
|
||
],
|
||
"expected": "잠금전비공개·잠금후허용범위",
|
||
"side_effect": "none",
|
||
"required_data": "잠금 전·후 상태가 분리된 종료 테스트 회기 2개",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "R11",
|
||
"actor": "learner_test",
|
||
"goal": "비식별가짜이름피드백",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; [NAME]만 포함한 비식별 테스트 축어록이 있는 종료 회기",
|
||
"steps": [
|
||
"‘축어록’ 탭을 연다.",
|
||
"[NAME]이 있던 테스트 문장이 ‘익명 인물은’ 또는 ‘익명 인물이’로 표시되는지 확인한다.",
|
||
"[NAME] 토큰이나 실제 이름이 화면에 남지 않는지 확인한다."
|
||
],
|
||
"expected": "상담자/내담자역할치환·실명미노출(실제개인정보금지)",
|
||
"side_effect": "none",
|
||
"required_data": "실제 개인정보 없이 [NAME] 토큰만 가진 테스트 축어록",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "R12",
|
||
"actor": "learner_test",
|
||
"goal": "워크시트빈필수제출",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; 워크시트 자동 초안이 있는 종료 테스트 회기",
|
||
"steps": [
|
||
"‘워크시트’ 탭에서 ‘사례개념화 워크시트’를 연다.",
|
||
"현재 소스의 저장 버튼은 빈 필수값 검증이 아니라 변경 여부만 확인함을 확인한다.",
|
||
"빈 필수 제출용 검증 문구가 없으므로 임의 저장을 하지 않고 BLOCKED로 기록한다."
|
||
],
|
||
"expected": "검증안내",
|
||
"side_effect": "none",
|
||
"required_data": "빈 필수값 검증이 실제로 배포된 테스트 환경",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "R13",
|
||
"actor": "learner_test",
|
||
"goal": "테스트워크시트작성저장",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; 저장되지 않은 워크시트 자동 초안이 있는 종료 테스트 회기",
|
||
"steps": [
|
||
"‘워크시트’ 탭에서 첫 번째 표시된 워크시트 textarea를 찾는다.",
|
||
"해당 aria-label이 나타내는 항목에 ‘비개인정보 실습 메모: 감정을 요약하고 개방형 질문을 이어간다.’를 입력한다.",
|
||
"활성화된 ‘저장’을 한 번 클릭한다.",
|
||
"상태가 ‘저장된 학습자 제출본’ 또는 ‘저장됨’으로 바뀌는지 확인한다."
|
||
],
|
||
"expected": "저장성공",
|
||
"side_effect": "test_data_mutation",
|
||
"required_data": "소유자 허용을 받은 워크시트 자동 초안과 비개인정보 메모",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "R14",
|
||
"actor": "learner_test",
|
||
"goal": "워크시트다시열기",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; R13 저장본이 있는 종료 테스트 회기",
|
||
"steps": [
|
||
"‘워크시트’ 탭에서 저장한 비개인정보 메모를 확인한다.",
|
||
"‘축어록’ 탭으로 이동한 뒤 다시 ‘워크시트’ 탭을 연다.",
|
||
"상태가 ‘저장된 학습자 제출본’이고 저장한 문장이 유지되는지 확인한다."
|
||
],
|
||
"expected": "내용보존",
|
||
"side_effect": "none",
|
||
"required_data": "저장 완료된 테스트 워크시트",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "R15",
|
||
"actor": "learner_test",
|
||
"goal": "피드백OFF 테스트계정",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; learnerFeedbackEnabled=false로 사전 설정된 종료 테스트 계정·회기",
|
||
"steps": [
|
||
"‘피드백’ 탭을 연다.",
|
||
"‘먼저 예측하고 잠그는 내 기록만 보존합니다’ 제목을 확인한다.",
|
||
"‘감정 밸런스 타임라인’, ‘좋았던 순간’, ‘다음 회기 개선점’ 등 파생 피드백 카드가 표시되지 않는지 확인한다."
|
||
],
|
||
"expected": "피드백/파생카드차단(사전설정필요)",
|
||
"side_effect": "none",
|
||
"required_data": "피드백 OFF가 확인된 테스트 계정과 종료 회기",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "R16",
|
||
"actor": "learner_test",
|
||
"goal": "피드백ON 테스트계정",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; learnerFeedbackEnabled=true로 사전 설정된 종료 테스트 계정·회기",
|
||
"steps": [
|
||
"‘피드백’ 탭을 연다.",
|
||
"‘먼저 예측하고, 잠근 뒤, 근거로 교정하기’ 제목을 확인한다.",
|
||
"평가 데이터가 있으면 해당 카드가, 없으면 ‘평가 대기’ 또는 ‘아직 생성된 내담자 피드백이 없습니다.’가 표시되는지 확인한다."
|
||
],
|
||
"expected": "정상표시(사전설정필요)",
|
||
"side_effect": "none",
|
||
"required_data": "피드백 ON이 확인된 테스트 계정과 종료 회기",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "R17",
|
||
"actor": "learner_test",
|
||
"goal": "리뷰에서다음회기준비",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; 전이 또는 처방 반환 intent가 있는 종료 테스트 회기",
|
||
"steps": [
|
||
"‘피드백’ 탭에서 반환 intent의 ‘같은 전이 과제로 다시 연습’ 또는 ‘같은 처방으로 다시 연습’을 찾는다.",
|
||
"링크의 출처·성공 기준 안내를 확인한다.",
|
||
"해당 링크를 열어 /learn/practice 주소에 원본 intent 검색값이 유지되는지 확인한다.",
|
||
"기존 리뷰 주소와 저장된 축어록을 다시 열어 남아 있는지 확인한다."
|
||
],
|
||
"expected": "같은사례로이동·기존기록보존",
|
||
"side_effect": "none",
|
||
"required_data": "검증된 반환 intent가 있는 테스트 회기",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "R18",
|
||
"actor": "learner_test",
|
||
"goal": "비교가능2회리뷰",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; 같은 비식별 사례의 종료 테스트 회기 2개",
|
||
"steps": [
|
||
"첫 번째 /review에서 ‘축어록’과 ‘피드백’의 회기 ID·근거 턴을 기록한다.",
|
||
"두 번째 /review를 열어 같은 항목을 기록한다.",
|
||
"각 화면이 자기 주소의 회기 ID와 축어록만 표시하고 근거가 섞이지 않는지 대조한다."
|
||
],
|
||
"expected": "각회기근거구분",
|
||
"side_effect": "none",
|
||
"required_data": "같은 사례에 속한 종료 테스트 회기 2개",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "R19",
|
||
"actor": "learner_test",
|
||
"goal": "모바일리뷰탭/폼",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; 390×844 모바일 뷰포트; 예측 입력 가능한 종료 테스트 회기",
|
||
"steps": [
|
||
"390×844에서 /learn/session/{테스트회기ID}/review를 연다.",
|
||
"‘축어록’, ‘피드백’, ‘워크시트’ 탭을 차례로 눌러 각각의 패널이 보이는지 확인한다.",
|
||
"‘피드백’ 탭에서 ‘성공 가능성’과 ‘그렇게 예상한 이유’ 입력란을 스크롤해 완전히 조작 가능한지 확인한다.",
|
||
"가로 스크롤이나 화면 밖에 가려진 탭·입력란이 없는지 확인한다."
|
||
],
|
||
"expected": "가로넘침/가려진조작없이완료",
|
||
"side_effect": "none",
|
||
"required_data": "모바일 뷰포트와 예측 입력 가능한 종료 테스트 회기",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "R20",
|
||
"actor": "learner_test",
|
||
"goal": "평가실패회기재시도",
|
||
"preconditions": "learner_test 로그인; 실제 배포본; 자연 발생한 session_end 평가 실패가 기록된 테스트 전용 회기",
|
||
"steps": [
|
||
"‘리뷰 생성 상태’에 실제 평가 실패와 재시도 제어가 보이는지 확인한다.",
|
||
"실패 원인 안내와 저장된 축어록을 읽는다.",
|
||
"자연 발생 실패 데이터가 없으면 재평가 요청이나 장애 유발을 하지 않고 BLOCKED로 기록한다."
|
||
],
|
||
"expected": "상태안내·기록보존·다음회기막힘없음(실제실패데이터필요)",
|
||
"side_effect": "none",
|
||
"required_data": "자연 발생 session_end 평가 실패가 보존된 테스트 회기",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "H01",
|
||
"actor": "learner_test",
|
||
"goal": "기록목록이동",
|
||
"preconditions": "인증된 학습자 테스트 계정",
|
||
"steps": [
|
||
"인증된 학습자 테스트 계정으로 `/learn/history`를 연다.",
|
||
"`회기 기록을 찾고 정리합니다.` 제목과 `회기 기록` 영역을 확인한다.",
|
||
"`회기 기록 목록`의 각 카드에 현재 계정의 페르소나 code·상태·단계·턴 수·날짜가 표시되는지 확인한다."
|
||
],
|
||
"expected": "실계정자기기록",
|
||
"side_effect": "none",
|
||
"required_data": "인증된 테스트 계정; 실제 배포 데이터는 읽기 전용으로 관찰",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "H02",
|
||
"actor": "learner_test",
|
||
"goal": "기록검색",
|
||
"preconditions": "인증된 학습자 테스트 계정; 검색 가능한 테스트 페르소나 code 또는 상태 문자열",
|
||
"steps": [
|
||
"`/learn/history`의 `aria-label=기록 검색` 입력에 테스트 페르소나 code 또는 상태 문자열을 입력한다.",
|
||
"목록 상단의 결과 수와 `회기 기록 목록` 카드를 확인한다.",
|
||
"표시된 카드의 code·단계·상태 중 적어도 하나가 입력한 검색어와 일치하는지 확인한다."
|
||
],
|
||
"expected": "일치회기만",
|
||
"side_effect": "none",
|
||
"required_data": "검색 가능한 테스트 페르소나 code 또는 상태 문자열",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "H03",
|
||
"actor": "learner_test",
|
||
"goal": "검색결과없음",
|
||
"preconditions": "인증된 학습자 테스트 계정",
|
||
"steps": [
|
||
"`기록 검색`에 존재하지 않는 임의 문자열을 입력한다.",
|
||
"빈 상태 문구와 결과 수 0을 확인한다.",
|
||
"입력 내용을 모두 지운다.",
|
||
"`전체 회기`과 기존 목록이 다시 표시되는지 확인한다."
|
||
],
|
||
"expected": "빈상태와검색해제복구",
|
||
"side_effect": "none",
|
||
"required_data": "인증된 테스트 계정; 실제 배포 데이터는 읽기 전용으로 관찰",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "H04",
|
||
"actor": "learner_test",
|
||
"goal": "진행중필터",
|
||
"preconditions": "인증된 학습자 테스트 계정; 진행 중 테스트 회기",
|
||
"steps": [
|
||
"`/learn/history`의 `기록 상태 필터`에서 `진행 중` 버튼을 누른다.",
|
||
"버튼의 `aria-pressed=true`와 제목 `진행 중`을 확인한다.",
|
||
"각 결과 카드에 `이어하기`가 있고 종료 카드용 `리뷰`·`기록` 조작이 섞이지 않는지 확인한다."
|
||
],
|
||
"expected": "이어가기대상만",
|
||
"side_effect": "none",
|
||
"required_data": "진행 중 테스트 회기",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "H05",
|
||
"actor": "learner_test",
|
||
"goal": "종료필터",
|
||
"preconditions": "인증된 학습자 테스트 계정; 종료 테스트 회기; 기능확인필요; 기능확인필요",
|
||
"steps": [
|
||
"`/learn/history`에서 종료된 테스트 기록을 먼저 찾는다.",
|
||
"소스의 상태 필터에는 `종료` 항목이 확인되지 않고 `전체`, `진행 중`, `리뷰 필요`, `보관됨`만 있으므로 실제 배포에서 `종료` 필터가 있는지 확인한다.",
|
||
"`종료` 필터가 있으면 정확한 버튼 라벨·결과 카드 상태를 기록한다.",
|
||
"없으면 기존 필터를 임의로 대체하지 않고 `기능확인필요`로 기록한다."
|
||
],
|
||
"expected": "완료대상만",
|
||
"side_effect": "none",
|
||
"required_data": "종료 테스트 회기; 기능확인필요",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "H06",
|
||
"actor": "learner_test",
|
||
"goal": "리뷰필요필터",
|
||
"preconditions": "인증된 학습자 테스트 계정; 리뷰 준비 상태 테스트 회기",
|
||
"steps": [
|
||
"`/learn/history`의 `기록 상태 필터`에서 `리뷰 필요` 버튼을 누른다.",
|
||
"`aria-pressed=true`와 목록 제목 `리뷰 필요`를 확인한다.",
|
||
"각 결과 카드가 `리뷰` 조작을 제공하고 `리뷰 가능` 상태인지 확인한다."
|
||
],
|
||
"expected": "리뷰대상만",
|
||
"side_effect": "none",
|
||
"required_data": "리뷰 준비 상태 테스트 회기",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "H07",
|
||
"actor": "learner_test",
|
||
"goal": "검색+상태조합",
|
||
"preconditions": "인증된 학습자 테스트 계정",
|
||
"steps": [
|
||
"`기록 검색`에 테스트 페르소나 code를 입력한다.",
|
||
"`기록 상태 필터`에서 `진행 중` 또는 `리뷰 필요`를 선택한다.",
|
||
"검색어를 유지한 채 결과 카드가 선택한 상태와 code 조건을 모두 만족하는지 확인한다."
|
||
],
|
||
"expected": "두조건유지",
|
||
"side_effect": "none",
|
||
"required_data": "인증된 테스트 계정; 실제 배포 데이터는 읽기 전용으로 관찰",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "H08",
|
||
"actor": "learner_test",
|
||
"goal": "목록정렬",
|
||
"preconditions": "인증된 학습자 테스트 계정; 기능확인필요",
|
||
"steps": [
|
||
"`/learn/history`를 열고 카드의 시작 날짜를 위에서 아래로 기록한다.",
|
||
"소스는 `sessionSortTime` 내림차순 정렬이며 UI 정렬 버튼은 확인되지 않았으므로 실제 배포에 정렬 조작이 있는지 확인한다.",
|
||
"정렬 조작이 있으면 라벨과 전후 날짜 순서를 기록한다.",
|
||
"정렬 조작이 없으면 날짜 내림차순 목록만 관찰하고 `기능확인필요`로 기록한다."
|
||
],
|
||
"expected": "날짜기준일관",
|
||
"side_effect": "none",
|
||
"required_data": "인증된 테스트 계정; 실제 배포 데이터는 읽기 전용으로 관찰",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "H09",
|
||
"actor": "learner_test",
|
||
"goal": "특정기록열고뒤로",
|
||
"preconditions": "인증된 학습자 테스트 계정",
|
||
"steps": [
|
||
"검색어 또는 `리뷰 필요` 필터를 적용한 `/learn/history`에서 특정 카드의 `리뷰` 또는 `기록` 버튼을 누른다.",
|
||
"회기 리뷰의 URL에 해당 session ID가 포함되는지 확인한다.",
|
||
"브라우저 뒤로가기로 `/learn/history`에 돌아온다.",
|
||
"검색어·필터·결과 목록 맥락이 복귀 후 유지되는지 확인한다."
|
||
],
|
||
"expected": "목록맥락복귀",
|
||
"side_effect": "none",
|
||
"required_data": "인증된 테스트 계정; 실제 배포 데이터는 읽기 전용으로 관찰",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "H10",
|
||
"actor": "learner_test",
|
||
"goal": "테스트종료기록보관",
|
||
"preconditions": "인증된 학습자 테스트 계정; 소유자 허용 뒤 폐기 가능 종료 테스트 회기",
|
||
"steps": [
|
||
"소유자가 명시적으로 허용한 폐기 가능 종료 테스트 회기만 `/learn/history`에서 찾는다.",
|
||
"대상 카드의 code·날짜·턴 수를 증거로 기록하고 `보관` 버튼을 확인한다.",
|
||
"허용이 없으면 버튼을 누르지 않고 safety gate와 `NOT_RUN`을 유지한다.",
|
||
"허용이 있으면 `보관`을 누르고 `회기를 보관했습니다.`와 카드의 `복원` 전환을 확인한다.",
|
||
"`보관됨` 필터에서 같은 code·날짜·턴 수의 원본 카드가 남아 있는지 확인한다."
|
||
],
|
||
"expected": "보관목록이동·원본보존(사용자허용필요)",
|
||
"side_effect": "test_data_mutation_requires_owner_approval",
|
||
"required_data": "소유자 허용 뒤 폐기 가능 종료 테스트 회기",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "H11",
|
||
"actor": "learner_test",
|
||
"goal": "보관기록복원",
|
||
"preconditions": "인증된 학습자 테스트 계정; 소유자 허용 뒤 보관된 폐기 가능 테스트 회기",
|
||
"steps": [
|
||
"소유자가 명시적으로 허용한 보관된 폐기 가능 테스트 회기만 `보관됨` 필터에서 찾는다.",
|
||
"대상 카드의 code·날짜·턴 수를 기록하고 `복원` 버튼을 확인한다.",
|
||
"허용이 없으면 버튼을 누르지 않고 safety gate와 `NOT_RUN`을 유지한다.",
|
||
"허용이 있으면 `복원`을 누르고 `보관을 해제했습니다.`를 확인한다.",
|
||
"`전체 회기` 또는 원래 상태 필터에서 같은 원본 카드가 다시 보이는지 확인한다."
|
||
],
|
||
"expected": "원래목록복귀",
|
||
"side_effect": "test_data_mutation_requires_owner_approval",
|
||
"required_data": "소유자 허용 뒤 보관된 폐기 가능 테스트 회기",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "H12",
|
||
"actor": "learner_test",
|
||
"goal": "설정화면조회",
|
||
"preconditions": "인증된 학습자 테스트 계정",
|
||
"steps": [
|
||
"인증된 학습자 테스트 계정으로 `/settings`를 연다.",
|
||
"설정 레일의 `계정` 버튼을 선택한다.",
|
||
"`계정 요약`과 `표시 이름`, `이메일`, `소속` 필드를 확인한다.",
|
||
"이메일 입력이 비활성화된 로그인 계정 정보인지 확인한다."
|
||
],
|
||
"expected": "자기계정정보",
|
||
"side_effect": "none",
|
||
"required_data": "인증된 테스트 계정; 실제 배포 데이터는 읽기 전용으로 관찰",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "H13",
|
||
"actor": "learner_test",
|
||
"goal": "테스트계정프로필수정후복원",
|
||
"preconditions": "인증된 학습자 테스트 계정; 소유자 허용 뒤 원래 값을 복원할 수 있는 테스트 계정",
|
||
"steps": [
|
||
"소유자가 허용한 테스트 계정으로 `/settings`의 `계정` 섹션을 연다.",
|
||
"`표시 이름`과 `소속`의 원래 값을 증거로 기록한다.",
|
||
"한 필드만 비식별 테스트 값으로 바꾸고 `저장`을 누른 뒤 `저장됨`을 확인한다.",
|
||
"새로고침 후 같은 테스트 값이 재조회되는지 확인한다.",
|
||
"원래 값을 다시 입력해 `저장`하고 새로고침하여 원복을 확인한다."
|
||
],
|
||
"expected": "저장/재조회일관(기존값보존)",
|
||
"side_effect": "test_data_mutation_requires_owner_approval",
|
||
"required_data": "소유자 허용 뒤 원래 값을 복원할 수 있는 테스트 계정",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "H14",
|
||
"actor": "learner_test",
|
||
"goal": "설정변경취소",
|
||
"preconditions": "인증된 학습자 테스트 계정",
|
||
"steps": [
|
||
"인증된 학습자 테스트 계정으로 `/settings`의 `계정` 섹션을 연다.",
|
||
"`표시 이름` 또는 `소속`에 저장하지 않을 임시 값을 입력한다.",
|
||
"사이드 레일의 다른 설정 섹션(예: `테마`)을 선택한 뒤 `계정`으로 돌아온다.",
|
||
"저장하지 않은 임시 값이 영속화되지 않았고 원래 값이 다시 표시되는지 확인한다."
|
||
],
|
||
"expected": "기존값보존",
|
||
"side_effect": "none",
|
||
"required_data": "인증된 테스트 계정; 실제 배포 데이터는 읽기 전용으로 관찰",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "T01",
|
||
"actor": "teacher_test",
|
||
"goal": "교수자로그인홈",
|
||
"preconditions": "승인된 teacher_test 계정으로 로그인 완료; 실제 배포본 https://vignette.chanpaca.net; 비식별 테스트 회기만 조회",
|
||
"steps": [
|
||
"로그인된 teacher_test 세션에서 /teach 를 연다.",
|
||
"상단 역할 표기가 ‘교수자’이고 제목이 ‘교수 콘솔’인지 확인한다.",
|
||
"‘학생 분석’과 ‘새로고침’ 버튼이 표시되는지 확인한다.",
|
||
"주소가 /teach 이고 관리자 편집 제어가 보이지 않는지 기록한다."
|
||
],
|
||
"expected": "허용콘솔",
|
||
"side_effect": "auth_session",
|
||
"required_data": "teacher_test 계정",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "T02",
|
||
"actor": "learner_test",
|
||
"goal": "학습자권한교수주소시도",
|
||
"preconditions": "인증된 learner_test 역할의 실제 브라우저 세션; admin 역할·admin 공간 전환으로 대체 검증 금지",
|
||
"steps": [
|
||
"teacher_test 세션에서 /admin/users 주소를 직접 연다.",
|
||
"관리자 사용자 목록이나 ‘가입 승인과 권한 관리’가 표시되지 않는지 확인한다.",
|
||
"권한 오류, 차단 화면 또는 허용된 교수자 경로로의 전환을 확인한다.",
|
||
"주소와 화면의 접근 차단 상태를 기록한다."
|
||
],
|
||
"expected": "차단",
|
||
"side_effect": "none",
|
||
"required_data": "learner_test 계정; 관리자 계정은 접근거부 PASS를 대체하지 않음",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "T03",
|
||
"actor": "teacher_test",
|
||
"goal": "대기목록에서테스트학습자리뷰",
|
||
"preconditions": "승인된 teacher_test 로그인 완료; 비식별 test_learner와 종료·review_ready 테스트 회기 1건이 교수자 큐에 존재",
|
||
"steps": [
|
||
"/teach 에서 test_learner가 포함된 최근 회기 행을 찾는다.",
|
||
"그 행의 ‘상세 리뷰’ 동작을 선택한다.",
|
||
"주소가 /teach/session/{test_session_id}/review 이고 리뷰 헤더의 학습자·세션이 선택 행과 일치하는지 확인한다.",
|
||
"리뷰 생성 상태가 ‘준비됨’인지 확인한다."
|
||
],
|
||
"expected": "대상일치",
|
||
"side_effect": "none",
|
||
"required_data": "test_learner 표시명, 종료·review_ready 테스트 session_id",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "T04",
|
||
"actor": "teacher_test",
|
||
"goal": "종료상태와리뷰상태구분",
|
||
"preconditions": "승인된 teacher_test 로그인 완료; 종료된 test_learner 회기 2건(검토 대기 1건, 검토 완료 또는 메모 저장 1건) 존재",
|
||
"steps": [
|
||
"/teach 에서 두 테스트 회기의 종료 상태와 검토 배지를 확인한다.",
|
||
"검토 대기 행과 검토 완료 또는 메모 저장 행을 각각 연다.",
|
||
"각 상세 리뷰의 세션 종료 표시와 교수자 검토 상태가 행의 배지와 일치하는지 확인한다.",
|
||
"종료 여부와 검토 여부가 하나의 같은 상태로 합쳐져 표시되지 않는지 기록한다."
|
||
],
|
||
"expected": "대기/완료명확",
|
||
"side_effect": "none",
|
||
"required_data": "상태가 다른 비식별 종료 테스트 회기 2건",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "T05",
|
||
"actor": "teacher_test",
|
||
"goal": "학습자검색",
|
||
"preconditions": "승인된 teacher_test 로그인 완료; test_learner의 표시명 또는 비식별 ID가 학생 분석 목록에 존재",
|
||
"steps": [
|
||
"/teach/analysis 에서 ‘학습자 검색’ 입력칸을 찾는다.",
|
||
"test_learner의 고유 검색 문자열을 입력한다.",
|
||
"검색 가능한 학습자 추이 테이블에 해당 학습자만 남는지 확인한다.",
|
||
"남은 행의 표시명 또는 ID가 입력한 테스트 대상과 일치하는지 확인한다."
|
||
],
|
||
"expected": "일치대상",
|
||
"side_effect": "none",
|
||
"required_data": "test_learner 표시명 또는 비식별 ID",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "T06",
|
||
"actor": "teacher_test",
|
||
"goal": "미일치검색복구",
|
||
"preconditions": "승인된 teacher_test 로그인 완료; 학생 분석 목록에 test_learner 존재",
|
||
"steps": [
|
||
"/teach/analysis 의 ‘학습자 검색’에 존재하지 않는 비식별 문자열을 입력한다.",
|
||
"‘검색 결과 없음’ 빈 상태와 검색어를 줄이라는 안내를 확인한다.",
|
||
"입력값을 모두 지운다.",
|
||
"test_learner 행이 다시 표시되고 이전 빈 상태가 사라지는지 확인한다."
|
||
],
|
||
"expected": "빈상태/해제정상",
|
||
"side_effect": "none",
|
||
"required_data": "존재하지 않는 비식별 검색 문자열, test_learner",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "T07",
|
||
"actor": "teacher_test",
|
||
"goal": "최신활동정렬",
|
||
"preconditions": "승인된 teacher_test 로그인 완료; 서로 다른 최근 활동 시각을 가진 비식별 학습자 2명 이상 존재",
|
||
"steps": [
|
||
"/teach/analysis 의 ‘학습자 정렬’에서 최신 활동 정렬 제어를 선택한다.",
|
||
"목록 첫 두 행의 최근 활동 시각 또는 같은 기준으로 표시된 최신 회기를 확인한다.",
|
||
"첫 행이 둘째 행보다 오래되지 않았는지 확인한다.",
|
||
"정렬 전후 선택한 학습자 검색 조건이 유지되는지 확인한다."
|
||
],
|
||
"expected": "목록정렬일관",
|
||
"side_effect": "none",
|
||
"required_data": "최근 활동 시각이 다른 test_learner 2명 이상",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "T08",
|
||
"actor": "teacher_test",
|
||
"goal": "회기수정렬",
|
||
"preconditions": "승인된 teacher_test 로그인 완료; 완료 회기 수가 다른 비식별 학습자 2명 이상 존재",
|
||
"steps": [
|
||
"/teach/analysis 의 ‘학습자 정렬’에서 회기 수 정렬 제어를 선택한다.",
|
||
"표의 ‘회기’ 열에서 첫 두 행의 수치를 확인한다.",
|
||
"선택한 정렬 방향과 수치 순서가 일치하는지 확인한다.",
|
||
"행을 새로 열지 않아도 정렬이 화면 값만 바꾸고 데이터를 수정하지 않는지 확인한다."
|
||
],
|
||
"expected": "값과순서일치",
|
||
"side_effect": "none",
|
||
"required_data": "완료 회기 수가 다른 test_learner 2명 이상",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "T09",
|
||
"actor": "teacher_test",
|
||
"goal": "학습자요약펼침닫힘",
|
||
"preconditions": "승인된 teacher_test 로그인 완료; 학생 분석 목록에 비식별 학습자 2명 이상 존재",
|
||
"steps": [
|
||
"/teach/analysis 에서 첫 test_learner 행의 ‘요약 펼치기’ 버튼을 선택한다.",
|
||
"그 행에만 회기·점수·추이 요약이 열리는지 확인한다.",
|
||
"같은 행의 ‘요약 접기’를 선택한다.",
|
||
"둘째 행의 펼침 상태와 표시 값이 바뀌지 않았는지 확인한다."
|
||
],
|
||
"expected": "다른행상태오염없음",
|
||
"side_effect": "none",
|
||
"required_data": "test_learner 2명 이상",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "T10",
|
||
"actor": "teacher_test",
|
||
"goal": "상세분석진입복귀",
|
||
"preconditions": "승인된 teacher_test 로그인 완료; test_learner가 학생 분석 목록에 존재",
|
||
"steps": [
|
||
"/teach/analysis 에서 test_learner 행의 ‘상세 보기’를 선택한다.",
|
||
"상세 제목의 학습자 표시명이 선택한 행과 같은지 확인한다.",
|
||
"상단 ‘콘솔로’ 버튼을 선택한다.",
|
||
"/teach 로 돌아오고 로그인 역할이 교수자로 유지되는지 확인한다."
|
||
],
|
||
"expected": "같은학습자맥락",
|
||
"side_effect": "none",
|
||
"required_data": "test_learner",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "T11",
|
||
"actor": "teacher_test",
|
||
"goal": "분석탭전환",
|
||
"preconditions": "승인된 teacher_test 로그인 완료; 상세 분석에 들어갈 test_learner 존재",
|
||
"steps": [
|
||
"test_learner의 상세 분석을 연다.",
|
||
"‘학습자 상세 분석 탭’에서 ‘페르소나별 회기’, ‘회기별 추이’, ‘전체 회기’, ‘단계 분포’를 차례로 선택한다.",
|
||
"각 탭에서 선택된 탭만 활성 상태이고 해당 섹션 제목 또는 빈 상태가 보이는지 확인한다.",
|
||
"탭 전환 뒤 학습자 이름과 분석 요약 수치가 동일 대상의 값으로 유지되는지 확인한다."
|
||
],
|
||
"expected": "선택에맞는데이터",
|
||
"side_effect": "none",
|
||
"required_data": "test_learner",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "T12",
|
||
"actor": "teacher_test",
|
||
"goal": "페르소나별기록그룹열기",
|
||
"preconditions": "승인된 teacher_test 로그인 완료; test_learner에 특정 페르소나 완료 회기 1건 이상 존재",
|
||
"steps": [
|
||
"test_learner 상세의 ‘페르소나별 회기’ 탭을 연다.",
|
||
"대상 페르소나의 ‘회기 펼치기’ 버튼을 선택한다.",
|
||
"펼친 그룹의 회기 수와 대상 session_id 또는 회기 번호가 사전 설정 자료와 일치하는지 확인한다.",
|
||
"다른 페르소나 그룹을 열지 않은 상태에서 대상 그룹만 확장되는지 확인한다."
|
||
],
|
||
"expected": "해당사례기록",
|
||
"side_effect": "none",
|
||
"required_data": "test_learner, 페르소나 코드, 해당 테스트 session_id",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "T13",
|
||
"actor": "teacher_test",
|
||
"goal": "회기타임라인개별리뷰",
|
||
"preconditions": "승인된 teacher_test 로그인 완료; test_learner의 종료·review_ready 테스트 session_id 존재",
|
||
"steps": [
|
||
"test_learner 상세의 ‘전체 회기’ 탭을 연다.",
|
||
"대상 회기 번호의 ‘상세 리뷰’ 또는 ‘진행 기록’ 버튼을 선택한다.",
|
||
"주소의 session_id와 타임라인에서 선택한 test_session_id가 일치하는지 확인한다.",
|
||
"종료 회기라면 리뷰 화면의 축어록 또는 리뷰 준비 상태가 표시되는지 확인한다."
|
||
],
|
||
"expected": "정확한회기",
|
||
"side_effect": "none",
|
||
"required_data": "test_learner, 종료·review_ready test_session_id",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "T14",
|
||
"actor": "teacher_test",
|
||
"goal": "추이차트부족데이터",
|
||
"preconditions": "승인된 teacher_test 로그인 완료; 평가 점수 또는 추이 표본이 부족한 test_learner 존재",
|
||
"steps": [
|
||
"표본 부족 test_learner의 상세 분석에서 ‘회기별 추이’를 연다.",
|
||
"차트가 값 없는 항목을 ‘저장된 점수 없음’ 또는 중립 빈 상태로 표시하는지 확인한다.",
|
||
"‘상승’·‘하락’ 같은 근거 없는 추이 단정이 표시되지 않는지 확인한다.",
|
||
"다른 탭의 회기 수와 차트에 표시된 표본 수가 모순되지 않는지 확인한다."
|
||
],
|
||
"expected": "무근거성과단정없음",
|
||
"side_effect": "none",
|
||
"required_data": "평가 표본 부족 test_learner",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "T15",
|
||
"actor": "teacher_test",
|
||
"goal": "테스트학습자검토메모임시작성취소",
|
||
"preconditions": "승인된 teacher_test 로그인 완료; 종료·review_ready test_session_id 존재",
|
||
"steps": [
|
||
"대상 /teach/session/{test_session_id}/review 의 교수자 검토 영역을 연다.",
|
||
"‘교수자 검토 메모’에 ‘CUA 임시 메모 - 저장 금지’를 입력한다.",
|
||
"‘메모 저장’을 누르지 않고 ‘전체 회기’ 탭으로 이동한 뒤 같은 리뷰를 다시 연다.",
|
||
"임시 문자열과 저장 시각이 남지 않았는지 확인한다."
|
||
],
|
||
"expected": "저장안됨",
|
||
"side_effect": "none",
|
||
"required_data": "비식별 종료 테스트 회기 1건",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "T16",
|
||
"actor": "teacher_test",
|
||
"goal": "테스트워크시트검토저장",
|
||
"preconditions": "승인된 teacher_test 로그인 완료; 소유자가 허용한 비식별 test_learner의 저장된 워크시트와 종료·review_ready test_session_id 존재; 테스트 뒤 정리 가능한 테스트 자료만 사용",
|
||
"steps": [
|
||
"대상 /teach/session/{test_session_id}/review 에서 ‘워크시트 검수’를 연다.",
|
||
"‘워크시트 검수 메모’에 비식별 테스트 문자열을 입력한다.",
|
||
"‘수정요청’을 실제로 선택하고 저장 완료 상태 또는 검수 시각이 표시될 때까지 기다린다.",
|
||
"같은 URL을 새로고침하거나 목록에서 다시 열어 메모·수정요청 상태·검수 시각이 같은 test_session_id에만 남았는지 재조회한다.",
|
||
"다른 테스트 회기의 워크시트 상태가 바뀌지 않았는지 확인한다."
|
||
],
|
||
"expected": "해당테스트항목만저장(승인필요)",
|
||
"side_effect": "test_data_mutation",
|
||
"required_data": "소유자 허용 비식별 워크시트 test_session_id, 저장된 학습자 워크시트",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "T17",
|
||
"actor": "teacher_test",
|
||
"goal": "안전큐대상열기",
|
||
"preconditions": "승인된 teacher_test 로그인 완료; 비식별 test_learner의 사전 설정 안전 알림 테스트 회기 존재",
|
||
"steps": [
|
||
"/teach 의 ‘위기 알림’ 큐에서 비식별 테스트 항목만 찾는다.",
|
||
"항목의 학습자 라벨·페르소나 코드·위험도·session_id 앞부분이 사전 설정한 테스트 자료와 일치하는지 확인한다.",
|
||
"큐가 원문 축어록이나 실제 연락처를 노출하지 않고 안내 번호·리소스 제목만 표시하는지 확인한다.",
|
||
"알림 상태를 승인·해결로 변경하지 않고 화면을 닫는다."
|
||
],
|
||
"expected": "해당테스트위기회기·안내(실제학생정보최소화)",
|
||
"side_effect": "none",
|
||
"required_data": "비식별 안전 알림 test_session_id",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "T18",
|
||
"actor": "teacher_test",
|
||
"goal": "감독·연구화면",
|
||
"preconditions": "승인된 teacher_test 로그인 완료; 실제 배포본 https://vignette.chanpaca.net",
|
||
"steps": [
|
||
"교수자 사이드바에서 ‘감독·연구’를 선택하거나 /teach/supervision 을 연다.",
|
||
"감독 우선순위와 증거 매니페스트 영역이 표시되는지 확인한다.",
|
||
"관리자 전용 지속 개선 승인 원장이나 사용자 권한 편집 제어가 표시되지 않는지 확인한다.",
|
||
"교수자 역할 표기와 주소가 유지되는지 기록한다."
|
||
],
|
||
"expected": "권한내기능표시",
|
||
"side_effect": "none",
|
||
"required_data": "teacher_test 계정",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "T19",
|
||
"actor": "teacher_test",
|
||
"goal": "모바일교수자목록검색리뷰",
|
||
"preconditions": "승인된 teacher_test 로그인 완료; 390px 폭; test_learner와 종료·review_ready test_session_id 존재",
|
||
"steps": [
|
||
"390px 폭에서 /teach/analysis 를 열고 ‘학습자 검색’에 test_learner를 입력한다.",
|
||
"가로 스크롤 없이 대상 행의 ‘상세 보기’를 선택한다.",
|
||
"‘전체 회기’ 탭에서 대상 session_id의 상세 리뷰를 연다.",
|
||
"리뷰 헤더·탭·뒤로가기 동작이 화면 밖으로 잘리지 않는지 확인한다."
|
||
],
|
||
"expected": "핵심동선조작가능",
|
||
"side_effect": "none",
|
||
"required_data": "test_learner, test_session_id",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "T20",
|
||
"actor": "teacher_test",
|
||
"goal": "교수자홈버튼",
|
||
"preconditions": "승인된 teacher_test 로그인 완료; 실제 배포본 https://vignette.chanpaca.net",
|
||
"steps": [
|
||
"/teach/analysis 를 열어 ‘학생 분석’ 화면인지 확인한다.",
|
||
"헤더의 ‘콘솔로’ 버튼을 선택한다.",
|
||
"주소가 정확히 /teach 로 바뀌고 제목이 ‘교수 콘솔’로 바뀌는지 확인한다.",
|
||
"경로가 유지되거나 잘못된 화면으로 이동하면 URL·화면 제목을 불일치 증거로 기록한다."
|
||
],
|
||
"expected": "정상/teach복귀(경로불일치후보확인)",
|
||
"side_effect": "none",
|
||
"required_data": "teacher_test 계정",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "O01",
|
||
"actor": "admin_test",
|
||
"goal": "관리자로그인홈",
|
||
"preconditions": "승인된 admin_test 계정으로 로그인 완료; 실제 배포본 https://vignette.chanpaca.net",
|
||
"steps": [
|
||
"로그인된 admin_test 세션에서 /admin 을 연다.",
|
||
"역할 표기가 ‘관리자’이고 제목이 ‘현재 서비스 상태’인지 확인한다.",
|
||
"‘새로고침’과 운영 요약이 표시되는지 확인한다.",
|
||
"사용자 변경·운영 설정 저장 버튼은 누르지 않는다."
|
||
],
|
||
"expected": "권한내콘솔",
|
||
"side_effect": "auth_session",
|
||
"required_data": "admin_test 계정",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "O02",
|
||
"actor": "learner_test",
|
||
"goal": "학습자관리주소",
|
||
"preconditions": "인증된 learner_test 역할의 실제 브라우저 세션; admin 역할·admin 공간 전환으로 대체 검증 금지",
|
||
"steps": [
|
||
"admin_test 세션에서 /learn 주소를 직접 연다.",
|
||
"학습자 홈의 학습 시작 제어와 개인 회기 목록이 관리자에게 표시되지 않는지 확인한다.",
|
||
"권한 오류, 차단 화면 또는 허용된 관리자 경로 전환을 확인한다.",
|
||
"주소와 접근 차단 상태를 기록한다."
|
||
],
|
||
"expected": "접근차단",
|
||
"side_effect": "none",
|
||
"required_data": "learner_test 계정; 관리자 계정은 접근거부 PASS를 대체하지 않음",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "O03",
|
||
"actor": "admin_test",
|
||
"goal": "운영홈서비스상태읽기",
|
||
"preconditions": "승인된 admin_test 로그인 완료; 실제 배포본 https://vignette.chanpaca.net",
|
||
"steps": [
|
||
"/admin 의 ‘현재 서비스 상태’에서 상태 문구·환경·엔진 모드·갱신 시각을 읽는다.",
|
||
"‘새로고침’을 한 번 선택하고 완료 뒤 갱신 시각이 표시되는지 확인한다.",
|
||
"운영 요약의 활성 회기·온라인 사용자 수가 숫자 또는 명시적 빈 값으로 표시되는지 확인한다.",
|
||
"상태 값을 변경하거나 진단 조치를 실행하지 않는다."
|
||
],
|
||
"expected": "실제상태/갱신시각명확",
|
||
"side_effect": "none",
|
||
"required_data": "admin_test 계정",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "O04",
|
||
"actor": "admin_test",
|
||
"goal": "AI운영기간변경",
|
||
"preconditions": "승인된 admin_test 로그인 완료; 실제 배포본 https://vignette.chanpaca.net",
|
||
"steps": [
|
||
"/admin/ai 의 ‘계량 기간’에서 현재 선택값을 기록한다.",
|
||
"표시된 다른 기간 버튼을 선택한다.",
|
||
"‘일별 비용 흐름’ 차트의 aria-label과 기간 표시가 선택한 일수로 바뀌는지 확인한다.",
|
||
"‘최근 집계’ 시각과 모델별 사용 원장이 새 기간 기준으로 다시 표시되는지 확인한다."
|
||
],
|
||
"expected": "집계기간반영",
|
||
"side_effect": "none",
|
||
"required_data": "admin_test 계정",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "O05",
|
||
"actor": "admin_test",
|
||
"goal": "모델별사용원장읽기",
|
||
"preconditions": "승인된 admin_test 로그인 완료; 선택 기간에 비식별 사용 원장 또는 명시적 빈 상태 존재",
|
||
"steps": [
|
||
"/admin/ai 에서 ‘AI 사용 핵심 지표’와 모델별 사용 원장 영역을 연다.",
|
||
"모델명, 호출 수, 토큰 또는 비용 단위, 비용 기준 라벨이 함께 표시되는지 확인한다.",
|
||
"미계량 호출이 있으면 복원하지 않고 미계량이라는 설명이 표시되는지 확인한다.",
|
||
"원문 프롬프트·응답·개인 식별 정보가 표에 보이지 않는지 확인한다."
|
||
],
|
||
"expected": "모델/계량단위명확",
|
||
"side_effect": "none",
|
||
"required_data": "admin_test 계정",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "O06",
|
||
"actor": "admin_test",
|
||
"goal": "AI설정열고취소",
|
||
"preconditions": "승인된 admin_test 로그인 완료; 현재 AI 엔진 설정이 조회 가능",
|
||
"steps": [
|
||
"/admin/ai 의 ‘AI 운영 설정’에서 현재 공급자·연결 주소·기본 모델·추론 강도를 기록한다.",
|
||
"저장 제어를 누르지 않고 모델 목록 또는 설정 영역만 연다.",
|
||
"‘운영 설정 저장’을 선택하지 않은 채 /admin 으로 이동한다.",
|
||
"다시 /admin/ai 를 열어 기록한 설정 값이 변하지 않았는지 확인한다."
|
||
],
|
||
"expected": "운영설정변경없음",
|
||
"side_effect": "none",
|
||
"required_data": "admin_test 계정, 현재 표시된 엔진 모드·모델 값",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "O07",
|
||
"actor": "admin_test",
|
||
"goal": "사용자검색",
|
||
"preconditions": "승인된 admin_test 로그인 완료; 비식별 test_learner 계정이 사용자 목록에 존재",
|
||
"steps": [
|
||
"/admin/users 에서 ‘사용자 목록’ 탭을 선택한다.",
|
||
"‘사용자 검색’에 test_learner의 고유 비식별 검색 문자열을 입력한다.",
|
||
"남은 행의 표시 이름·역할이 사전 설정한 테스트 계정과 일치하는지 확인한다.",
|
||
"행의 저장·승인·역할 선택 제어는 누르지 않는다."
|
||
],
|
||
"expected": "대상일치",
|
||
"side_effect": "none",
|
||
"required_data": "test_learner 표시명 또는 비식별 이메일 식별자",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "O08",
|
||
"actor": "admin_test",
|
||
"goal": "사용자검색없음",
|
||
"preconditions": "승인된 admin_test 로그인 완료; 사용자 목록 조회 가능",
|
||
"steps": [
|
||
"/admin/users 의 ‘사용자 목록’ 탭에서 ‘사용자 검색’에 존재하지 않는 문자열을 입력한다.",
|
||
"검색 조건에 맞는 사용자가 없다는 빈 상태가 표시되는지 확인한다.",
|
||
"검색어를 지운다.",
|
||
"목록이 돌아오고 사용자 편집값이 바뀌지 않았는지 확인한다."
|
||
],
|
||
"expected": "빈상태/복귀",
|
||
"side_effect": "none",
|
||
"required_data": "존재하지 않는 비식별 검색 문자열",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "O09",
|
||
"actor": "admin_test",
|
||
"goal": "사용자정렬",
|
||
"preconditions": "승인된 admin_test 로그인 완료; 사용자 목록에 비식별 계정 2개 이상 존재",
|
||
"steps": [
|
||
"/admin/users 의 ‘사용자 목록’에서 정렬 가능한 열 머리글을 선택한다.",
|
||
"첫 두 행의 해당 열 값을 기록한다.",
|
||
"같은 열 머리글을 다시 선택해 정렬 방향을 바꾼다.",
|
||
"방향 표시와 두 행의 값 순서가 일치하고 사용자 편집 제어가 실행되지 않았는지 확인한다."
|
||
],
|
||
"expected": "값/순서일관",
|
||
"side_effect": "none",
|
||
"required_data": "비식별 사용자 2개 이상",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "O10",
|
||
"actor": "admin_test",
|
||
"goal": "테스트사용자상세",
|
||
"preconditions": "승인된 admin_test 로그인 완료; 비식별 test_learner 계정이 사용자 목록에 존재",
|
||
"steps": [
|
||
"/admin/users 의 ‘사용자 목록’에서 test_learner를 검색한다.",
|
||
"해당 행을 펼쳐 표시 이름, 역할, 승인 상태, ‘학습자 AI 피드백’ 값을 확인한다.",
|
||
"표시된 역할·피드백 상태가 사전 설정된 테스트 값과 일치하는지 확인한다.",
|
||
"select·switch·저장 버튼을 조작하지 않고 행을 다시 접는다."
|
||
],
|
||
"expected": "역할/피드백상태확인",
|
||
"side_effect": "none",
|
||
"required_data": "test_learner 계정의 사전 설정 역할·AI 피드백 값",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "O11",
|
||
"actor": "admin_test",
|
||
"goal": "권한정책화면",
|
||
"preconditions": "승인된 admin_test 로그인 완료; 실제 배포본 https://vignette.chanpaca.net",
|
||
"steps": [
|
||
"/admin/access 에서 ‘역할’ 탭을 연다.",
|
||
"관리자·교수자·학습자 정책 카드와 권한 수가 표시되는지 확인한다.",
|
||
"‘권한 매트릭스’ 탭을 선택해 리소스별 세 역할 열이 표시되는지 확인한다.",
|
||
"화면이 정책 표시 전용이며 역할·그룹 저장 API가 분리되지 않았다는 안내를 확인한다."
|
||
],
|
||
"expected": "접근정책표시",
|
||
"side_effect": "none",
|
||
"required_data": "admin_test 계정",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "O12",
|
||
"actor": "admin_test",
|
||
"goal": "프로토콜메뉴접근",
|
||
"preconditions": "승인된 admin_test 로그인 완료; 프로토콜을 생성하지 않는 읽기 전용 확인",
|
||
"steps": [
|
||
"/admin/access 에서 aria-label ‘접근 권한 탭’의 ‘상담 프로토콜’을 선택한다.",
|
||
"‘상담 프로토콜 초안 등록’ 제목과 ‘등록 프로토콜’ 목록이 함께 표시되는지 확인한다.",
|
||
"‘프로토콜 제목’, ‘프로토콜 출처’, ‘프로토콜 버전’, ‘프로토콜 라이선스’, ‘프로토콜 원문’ 입력 제어를 확인한다.",
|
||
"초안 등록·활성화·퇴역 버튼은 누르지 않는다."
|
||
],
|
||
"expected": "목록/신규폼존재",
|
||
"side_effect": "none",
|
||
"required_data": "admin_test 계정",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "O13",
|
||
"actor": "admin_test",
|
||
"goal": "프로토콜검색상태필터",
|
||
"preconditions": "승인된 admin_test 로그인 완료; 제목 또는 상태가 알려진 비식별 테스트 프로토콜 존재",
|
||
"steps": [
|
||
"/admin/access 의 ‘상담 프로토콜’ 탭에서 ‘프로토콜 검색’에 테스트 제목 조각을 입력한다.",
|
||
"‘프로토콜 상태 필터’를 사전 설정 상태로 선택한다.",
|
||
"남은 카드의 제목과 상태 배지가 둘 다 기대값과 일치하는지 확인한다.",
|
||
"검색어와 필터를 원래 값으로 되돌리고 목록이 복구되는지 확인한다."
|
||
],
|
||
"expected": "일치항목",
|
||
"side_effect": "none",
|
||
"required_data": "비식별 테스트 프로토콜 제목 조각과 사전 설정 상태",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "O14",
|
||
"actor": "admin_test",
|
||
"goal": "프로토콜빈필수초안등록",
|
||
"preconditions": "승인된 admin_test 로그인 완료; 프로토콜 목록의 시작 개수 또는 대상 제목 부재를 기록",
|
||
"steps": [
|
||
"/admin/access 의 ‘상담 프로토콜’ 탭에서 필수 입력을 모두 빈 값으로 둔다.",
|
||
"‘초안 등록’을 한 번 선택한다.",
|
||
"‘제목, 출처, 원문을 모두 입력해야 합니다.’ 오류가 표시되는지 확인한다.",
|
||
"등록 프로토콜 목록에 새 카드가 생기지 않았는지 확인한다."
|
||
],
|
||
"expected": "오류안내·생성없음",
|
||
"side_effect": "none",
|
||
"required_data": "admin_test 계정",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "O15",
|
||
"actor": "admin_test",
|
||
"goal": "프로토콜초안작성취소",
|
||
"preconditions": "승인된 admin_test 로그인 완료; 프로토콜 목록과 기존 검색 결과를 기록",
|
||
"steps": [
|
||
"‘상담 프로토콜 초안 등록’에 비식별 임시 제목·출처·원문을 입력한다.",
|
||
"‘초안 등록’을 누르지 않고 ‘역할’ 탭으로 이동한다.",
|
||
"다시 ‘상담 프로토콜’ 탭을 열어 임시 입력이 새 카드로 생성되지 않았는지 확인한다.",
|
||
"기존 프로토콜 카드 수와 검색 결과가 시작 기록과 같은지 확인한다."
|
||
],
|
||
"expected": "기존자료영향없음",
|
||
"side_effect": "none",
|
||
"required_data": "비식별 임시 제목·출처·원문 문자열",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "O16",
|
||
"actor": "admin_test",
|
||
"goal": "티켓복합필터",
|
||
"preconditions": "승인된 admin_test 로그인 완료; 비식별 테스트 티켓이 사전 설정된 상태·카테고리·우선순위로 존재",
|
||
"steps": [
|
||
"/admin/tickets 에서 ‘티켓 검색’에 테스트 제목 조각을 입력한다.",
|
||
"‘상태 필터’, ‘카테고리 필터’, ‘우선순위 필터’를 사전 설정값으로 선택한다.",
|
||
"미해결 운영 티켓 큐에 남은 카드가 목표 티켓과 일치하는지 확인한다.",
|
||
"티켓 상태 변경·해결 노트 저장 제어는 누르지 않는다."
|
||
],
|
||
"expected": "일치티켓목록",
|
||
"side_effect": "none",
|
||
"required_data": "비식별 테스트 티켓의 제목 조각·상태·카테고리·우선순위",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "O17",
|
||
"actor": "admin_test",
|
||
"goal": "티켓상세열고복귀",
|
||
"preconditions": "승인된 admin_test 로그인 완료; O16의 복합 필터로 남는 비식별 테스트 티켓 존재",
|
||
"steps": [
|
||
"/admin/tickets 에서 O16과 같은 검색·필터를 적용한다.",
|
||
"남은 테스트 티켓의 상세 열기 제어를 선택한다.",
|
||
"제목·상태·카테고리가 선택한 카드와 일치하는지 확인한다.",
|
||
"뒤로 또는 목록 복귀 후 검색어와 필터, 남은 카드가 유지되는지 확인한다."
|
||
],
|
||
"expected": "필터맥락유지",
|
||
"side_effect": "none",
|
||
"required_data": "비식별 테스트 티켓",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "O18",
|
||
"actor": "admin_test",
|
||
"goal": "개선원장상태조회",
|
||
"preconditions": "승인된 admin_test 로그인 완료; 실제 배포본 https://vignette.chanpaca.net",
|
||
"steps": [
|
||
"/admin/continuous-improvement 를 열고 ‘승격보다 근거를 먼저 본다’ 헤더를 확인한다.",
|
||
"운영 경계, 콘텐츠 검증 단계, 게이트 필수 증거, 수명주기 원장을 차례로 확인한다.",
|
||
"후보의 증거 상태와 사람 승인 이후 효과가 다른 영역으로 분리되어 있는지 확인한다.",
|
||
"‘원장 새로고침’ 외의 승인·보류·반려 제어는 누르지 않는다."
|
||
],
|
||
"expected": "후보/증거/실행결정구분",
|
||
"side_effect": "none",
|
||
"required_data": "admin_test 계정",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "O19",
|
||
"actor": "admin_test",
|
||
"goal": "증거부족후보승인시도",
|
||
"preconditions": "승인된 admin_test 로그인 완료; 필수 증거가 부족한 비식별 후보가 지속 개선 원장에 존재",
|
||
"steps": [
|
||
"/admin/continuous-improvement 에서 증거 부족 후보의 ‘게이트 필수 증거’ 상태를 확인한다.",
|
||
"‘필수 증거 4종 미완료로 승인 차단’ 또는 해당 차단 사유를 확인한다.",
|
||
"그 후보의 승인 버튼이 disabled 상태인지 접근성 상태와 화면으로 확인한다.",
|
||
"승인·보류·반려 선택이나 제출 버튼은 어떤 것도 누르지 않고 차단 관찰만 기록한다."
|
||
],
|
||
"expected": "승인차단(실제승인제출금지)",
|
||
"side_effect": "none",
|
||
"required_data": "증거 부족 비식별 후보",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
},
|
||
{
|
||
"id": "O20",
|
||
"actor": "admin_test",
|
||
"goal": "모바일관리자검색상세",
|
||
"preconditions": "승인된 admin_test 로그인 완료; 390px 폭; 비식별 test_learner 계정 존재",
|
||
"steps": [
|
||
"390px 폭에서 /admin/users 의 ‘사용자 목록’ 탭을 연다.",
|
||
"‘사용자 검색’에 test_learner를 입력한다.",
|
||
"가로 스크롤 없이 대상 행의 상세를 열어 역할·승인 상태·학습자 AI 피드백 상태를 확인한다.",
|
||
"저장·승인·역할 변경 없이 상세를 닫고, 입력·필터·제어가 화면 밖으로 잘리지 않는지 확인한다."
|
||
],
|
||
"expected": "가로넘침없이핵심조작",
|
||
"side_effect": "none",
|
||
"required_data": "test_learner 표시명 또는 비식별 이메일 식별자",
|
||
"status": "NOT_RUN",
|
||
"evidence": []
|
||
}
|
||
]
|
||
}
|