UI 복잡 버전 234 RED→GREEN 완료(docs/UI_USECASES.md §A~§J): 라이브 테마 전환(DynamicResource 전환+ThemeResolver+HighContrast 테마, 재시작 없음), 디자인 토큰 체계·WCAG 대비 결함 5건 수정, 설정창 카테고리 내비/검색 재구성+AppConfig 40여 속성, 다운로드 관리자(속도/ETA/세그먼트맵/전체 일시정지-이어받기/CSV 내보내기/예약 게이트/중복 확인), 라이브러리·아카이브·작업공간·재생목록·즐겨찾기 편집 뷰, 접근성(자동화 속성 30여 개·커스텀 피어·docs/ACCESSIBILITY.md), 인터랙션(휠 클릭 새 탭·XButton 탐색·F12·영역 캡처·프로필 전환), 상태/알림(토스트·알림센터·온보딩·CrashReportDialog). 보강 테스트 35건+실창 E2E 4건(StaDispatcher 기반 — 프록시 설정이 기시작 핸들러를 건드리는 크래시 실결함 수정 포함) — 453/453 GREEN. 이전 미커밋 작업(CI 워크플로·Mdns·QueueHub·UpdateChecker·AGENTS/CLAUDE·빌드 스크립트) 일괄 포함

This commit is contained in:
Yun Chan 2026-08-17 15:54:53 +09:00
parent 5a0ce730b2
commit 17f2f91152
88 changed files with 9463 additions and 1127 deletions

View file

@ -0,0 +1,163 @@
using VideoDownloader.App;
using VideoDownloader.Browser;
using VideoDownloader.Core.Config;
using VideoDownloader.Tests.Infrastructure;
namespace VideoDownloader.Tests.E2E;
/// <summary>
/// UI 복잡 버전 RED 스펙 — §D 탭 고급 관리 유즈케이스(docs/UI_USECASES.md §D, UC-B01~B24).
/// RED 단계: 전부 실패하는 것이 정상이다.
/// </summary>
public class UiUsecaseTabsRedTests
{
private static readonly Type TabItemType =
SourceTree.FindType("TabItem") ?? throw new InvalidOperationException("Browser TabItem 형식을 찾을 수 없습니다");
[Fact]
public void UC_B01_탭을_잠글_수_있다()
=> SourceTree.Usecase(
SourceTree.PropertyExists(TabItemType, "IsLocked"),
"UC-B01", "탭 잠금(IsLocked)으로 실수로 닫는 것을 막을 수 있어야 한다");
[Fact]
public void UC_B02_탭마다_사용자_지정_색을_달_수_있다()
=> SourceTree.Usecase(
SourceTree.PropertyExists(TabItemType, "CustomColor"),
"UC-B02", "탭 사용자 샆(CustomColor) 속성이 필요하다");
[Fact]
public void UC_B03_탭_그룹을_접을_수_있다()
=> SourceTree.Usecase(
SourceTree.PropertyExists(TabItemType, "IsGroupCollapsed"),
"UC-B03", "그룹 접음(IsGroupCollapsed) 상태가 탭 항목에 있어야 한다");
[Fact]
public void UC_B04_탭_그룹_이름을_변경할_수_있다()
{
var ext = SourceTree.FindType("TabManagerGroupExtensions");
SourceTree.Usecase(
ext is not null && SourceTree.MethodExists(ext, "RenameGroup"),
"UC-B04", "그룹 이름 변경(RenameGroup) API 가 필요하다");
}
[Fact]
public void UC_B05_탭_호버_미리보기_컴포넌트가_있다()
=> SourceTree.Usecase(
SourceTree.FindType("TabPreview") is not null,
"UC-B05", "탭 호버 미리보기를 담당하는 TabPreview 컴포넌트가 필요하다");
[Fact]
public void UC_B06_잠자기_탭이_시각적으로_구분된다()
=> SourceTree.Usecase(
SourceTree.MainWindowXaml.Contains("IsSuspended"),
"UC-B06", "탭 템플릿이 잠자기 상태(IsSuspended)를 시각적으로 표시해야 한다");
[Fact]
public void UC_B07_탭_번호_배지가_표시된다()
=> SourceTree.Usecase(
SourceTree.MainWindowXaml.Contains("TabIndexBadge"),
"UC-B07", "탭 번호 배지(TabIndexBadge) 요소가 필요하다");
[Fact]
public void UC_B08_탭_드래그_삽입_표시기가_있다()
=> SourceTree.Usecase(
SourceTree.MainWindowXaml.Contains("TabInsertIndicator"),
"UC-B08", "드래그 중 삽입 위치 표시기(TabInsertIndicator)가 필요하다");
[Fact]
public void UC_B09_다중_탭_닫기_확인_옵션이_있다()
=> SourceTree.Usecase(
SourceTree.PropertyExists(typeof(AppConfig), "ConfirmCloseMultipleTabs"),
"UC-B09", "AppConfig.ConfirmCloseMultipleTabs 속성이 필요하다");
[Fact]
public void UC_B10_휠로_탭을_전환하는_옵션이_있다()
=> SourceTree.Usecase(
SourceTree.PropertyExists(typeof(AppConfig), "TabWheelSwitch"),
"UC-B10", "AppConfig.TabWheelSwitch 속성이 필요하다");
[Fact]
public void UC_B11_탭_최대_개수를_설정할_수_있다()
=> SourceTree.Usecase(
SourceTree.PropertyExists(typeof(AppConfig), "MaxTabs"),
"UC-B11", "AppConfig.MaxTabs 속성이 필요하다");
[Fact]
public void UC_B12_세션_복원을_잠자기_상태로_할_수_있다()
=> SourceTree.Usecase(
SourceTree.PropertyExists(typeof(AppConfig), "RestoreTabsSuspended"),
"UC-B12", "AppConfig.RestoreTabsSuspended 속성이 필요하다");
[Fact]
public void UC_B13_닫은_탭_아카이브_전용_팝업이_있다()
=> SourceTree.Usecase(
SourceTree.MainWindowXaml.Contains("Name=\"ArchivePopup\""),
"UC-B13", "아카이브를 보여주는 ArchivePopup 이 필요하다");
[Fact]
public void UC_B14_아카이브를_검색할_수_있다()
=> SourceTree.Usecase(
SourceTree.MainWindowXaml.Contains("ArchiveSearchBox"),
"UC-B14", "아카이브 검색 상자(ArchiveSearchBox)가 필요하다");
[Fact]
public void UC_B15_아카이브를_한번에_비울_수_있다()
=> SourceTree.Usecase(
SourceTree.MethodExists(typeof(TabArchive), "Clear"),
"UC-B15", "TabArchive.Clear() 메서드가 필요하다");
[Fact]
public void UC_B16_아카이브_항목을_복원할_수_있다()
=> SourceTree.Usecase(
SourceTree.MethodExists(typeof(TabArchive), "Restore"),
"UC-B16", "TabArchive.Restore() 메서드가 필요하다");
[Fact]
public void UC_B17_탭_그룹_색_팔레트가_테마로_관리된다()
=> SourceTree.Usecase(
SourceTree.HasKey(SourceTree.SharedXaml, "GroupPalette"),
"UC-B17", "그룹 색 팔레트(GroupPalette)가 공용 리소스로 정의되어야 한다");
[Fact]
public void UC_B18_현재_작업공간_이름이_표시된다()
=> SourceTree.Usecase(
SourceTree.MainWindowXaml.Contains("WorkspaceIndicator"),
"UC-B18", "현재 작업공간 표시(WorkspaceIndicator) 요소가 필요하다");
[Fact]
public void UC_B19_작업공간_이름을_직접_지을_수_있다()
=> SourceTree.Usecase(
SourceTree.PropertyExists(typeof(AppConfig), "WorkspaceNames"),
"UC-B19", "AppConfig.WorkspaceNames 속성이 필요하다");
[Fact]
public void UC_B20_작업공간_전환_UI가_있다()
=> SourceTree.Usecase(
SourceTree.MainWindowXaml.Contains("WorkspaceSwitcher"),
"UC-B20", "작업공간 전환기(WorkspaceSwitcher) 요소가 필요하다");
[Fact]
public void UC_B21_새_탭_버튼에_보조_메뉴가_있다()
=> SourceTree.Usecase(
SourceTree.MainWindowXaml.Contains("NewTabMore_Click"),
"UC-B21", "새 탭 버튼의 보조 메뉴(최근 페이지·즐겨찾기) 핸들러가 필요하다");
[Fact]
public void UC_B22_탭_제목을_두_줄로_볼_수_있다()
=> SourceTree.Usecase(
SourceTree.PropertyExists(typeof(AppConfig), "TabTitleMultiline"),
"UC-B22", "AppConfig.TabTitleMultiline 속성이 필요하다");
[Fact]
public void UC_B23_탭에서_볼륨_슬라이더를_쓸_수_있다()
=> SourceTree.Usecase(
SourceTree.MainWindowXaml.Contains("TabVolumePopup"),
"UC-B23", "탭 볼륨 조절 팝업(TabVolumePopup)이 필요하다");
[Fact]
public void UC_B24_탭_그룹을_즐겨찾기로_저장할_수_있다()
=> SourceTree.Usecase(
SourceTree.MethodExists(typeof(MainWindow), "BookmarkGroup"),
"UC-B24", "그룹 전체를 즐겨찾기로 저장하는 MainWindow.BookmarkGroup() 이 필요하다");
}