153 lines
7.8 KiB
C#
153 lines
7.8 KiB
C#
using System.Windows;
|
|
using Paca.App;
|
|
using Paca.Tests.Infrastructure;
|
|
|
|
namespace Paca.Tests.E2E;
|
|
|
|
/// <summary>
|
|
/// E2E (Phase A): 실제 MainWindow 기동 → WebView2 초기화 → about:blank 탐색 →
|
|
/// 다중 탭(생성/전환/닫기/Ctrl+Shift+T 복원) + 검색 바 + 전체화면까지 실 창에서 검증.
|
|
/// </summary>
|
|
[Collection("E2E")]
|
|
public class MainWindowSmokeE2ETests
|
|
{
|
|
[Fact]
|
|
public async Task MainWindow_기동_탐색_탭전환_닫기_복원_검색바_전체화면_E2E()
|
|
{
|
|
// VD_DATA_DIR 격리: 실사용자 설정/세션/프로필과 분리된 임시 데이터 디렉터리 (결정적 테스트)
|
|
var dataDir = Path.Combine(Path.GetTempPath(), $"vd_e2e_data_{Guid.NewGuid():N}");
|
|
Environment.SetEnvironmentVariable("VD_DATA_DIR", dataDir);
|
|
try
|
|
{
|
|
using var sta = StaDispatcher.Start();
|
|
WpfTestApp.Ensure(sta.Dispatcher);
|
|
var ok = await sta.InvokeAsync(async () =>
|
|
{
|
|
var window = new MainWindow();
|
|
window.Show();
|
|
|
|
// 첫 탭 WebView2 초기화 대기
|
|
var first = await Wait.Until(
|
|
() => Task.FromResult(window.Tabs.ActiveTab),
|
|
t => t?.Core != null, 30000);
|
|
Assert.NotNull(first);
|
|
var cv1 = first.Core!;
|
|
|
|
// about:blank 탐색 (네트워크 불필요)
|
|
window.NavigateTo("about:blank");
|
|
await Wait.Until(() => Task.FromResult(cv1.Source ?? ""), s => s.Contains("about:blank"), 15000);
|
|
|
|
// ── Phase A: 다중 탭 ──
|
|
var tab2 = window.Tabs.NewTab();
|
|
var cv2 = await Wait.Until(() => Task.FromResult(tab2.Core), c => c != null, 30000);
|
|
Assert.NotNull(cv2);
|
|
cv2.NavigateToString("<html><body><p id='x'>hello-tab2</p></body></html>");
|
|
await WaitUntilNavCompleted(cv2);
|
|
|
|
Assert.NotSame(first, window.Tabs.ActiveTab); // NewTab 이 활성화
|
|
Assert.Equal(2, window.Tabs.Tabs.Count);
|
|
|
|
// 탭 전환: 첫 탭으로
|
|
window.Tabs.Activate(first);
|
|
var switched = ReferenceEquals(window.Tabs.ActiveTab, first);
|
|
|
|
// 탭 닫기 → 오른쪽 이웃 활성화 → Ctrl+Shift+T 복원
|
|
window.Tabs.CloseTab(tab2);
|
|
var countAfterClose = window.Tabs.Tabs.Count;
|
|
var reopened = window.Tabs.ReopenClosedTab();
|
|
var countAfterReopen = window.Tabs.Tabs.Count;
|
|
|
|
// ── T1-3 검색 바 ──
|
|
window.OpenFind();
|
|
var findVisible = window.FindBar.Visibility == Visibility.Visible;
|
|
window.CloseFind();
|
|
var findCollapsed = window.FindBar.Visibility == Visibility.Collapsed;
|
|
|
|
// ── T1-11 전체화면 ──
|
|
window.ToggleFullscreen();
|
|
var toolbarHidden = window.ToolbarRow.Visibility == Visibility.Collapsed
|
|
&& window.TabStripRow.Visibility == Visibility.Collapsed;
|
|
window.ToggleFullscreen();
|
|
var toolbarBack = window.ToolbarRow.Visibility == Visibility.Visible;
|
|
|
|
// ── T3-13 컴팩트 모드: 크롬 행 높이 0 → 해제 시 복원 ──
|
|
window.ToggleCompactMode();
|
|
var compactRowZero = window.MainGrid.RowDefinitions[0].Height.Value == 0;
|
|
window.ToggleCompactMode();
|
|
var compactRowBack = window.MainGrid.RowDefinitions[0].Height.IsAuto;
|
|
|
|
// ── T3-12 노트: 패널 열림 + 현재 페이지 추가 → 목록 1건 ──
|
|
window.ToggleNotes();
|
|
var notesOpen = window.NotesPopup.IsOpen;
|
|
window.NotesAddPage_Click(window, new RoutedEventArgs());
|
|
var notesCount = window.Notes.List().Count;
|
|
window.NotesPopup.IsOpen = false;
|
|
|
|
// ── T3-2 아카이브: 위에서 닫았던 탭이 영속 아카이브에 기록 ──
|
|
// ── T3-2 아카이브: URL 있는 탭을 닫으면 영속 아카이브에 기록 ──
|
|
var tab3 = window.Tabs.NewTab();
|
|
await Wait.Until(() => Task.FromResult(tab3.Core), c => c != null, 30000);
|
|
tab3.Url = "https://e2e.test/archived-page"; // URL 확정 상태 시뮬레이션(실제는 SourceChanged 가 설정)
|
|
window.Tabs.CloseTab(tab3);
|
|
await Task.Delay(800); // 진행 중이던 초기 네비게이션 이벤트가 dispose 이후 터지지 않게 여유
|
|
var archivedCount = window.Archive.Search("").Count;
|
|
var archivedHasUrl = window.Archive.Search("").Any(a => a.Url.Contains("e2e.test"));
|
|
|
|
// ── T3-6 페이지 액션: 실제 HTTP 문서에서 흑백 적용 → 부스트 저장 ──
|
|
var port = Random.Shared.Next(21000, 59000);
|
|
using var server = new System.Net.HttpListener();
|
|
server.Prefixes.Add($"http://127.0.0.1:{port}/");
|
|
server.Start();
|
|
var serveTask = Task.Run(async () =>
|
|
{
|
|
var ctx = await server.GetContextAsync();
|
|
var bytes = System.Text.Encoding.UTF8.GetBytes("<html><body><p>page-action-e2e</p></body></html>");
|
|
await ctx.Response.OutputStream.WriteAsync(bytes);
|
|
ctx.Response.Close();
|
|
});
|
|
window.Tabs.Activate(first);
|
|
cv1.Navigate($"http://127.0.0.1:{port}/");
|
|
await Wait.Until(() => Task.FromResult(cv1.Source ?? ""), s => s.Contains("127.0.0.1"), 15000);
|
|
await serveTask.WaitAsync(TimeSpan.FromSeconds(10));
|
|
window.ApplyPageFilter(Paca.App.Browser.Features.PageFilter.Grayscale);
|
|
var filterSaved = window.BoostStore.Get($"http://127.0.0.1:{port}/").Filter;
|
|
server.Stop();
|
|
|
|
window.Close();
|
|
return (init: true, switched, countAfterClose, reopened: reopened != null, countAfterReopen,
|
|
findVisible, findCollapsed, toolbarHidden, toolbarBack,
|
|
compactRowZero, compactRowBack, notesOpen, notesCount, archivedCount, archivedHasUrl, filterSaved);
|
|
});
|
|
|
|
Assert.True(ok.init, "WebView2 초기화 실패");
|
|
Assert.True(ok.switched, "탭 전환 실패");
|
|
Assert.True(ok.countAfterClose == 1, $"탭 닫기 후 개수 오류: {ok.countAfterClose}");
|
|
Assert.True(ok.reopened, "닫은 탭 복원 실패");
|
|
Assert.True(ok.countAfterReopen == 2, $"복원 후 개수 오류: {ok.countAfterReopen}");
|
|
Assert.True(ok.findVisible, "검색 바 미표시");
|
|
Assert.True(ok.findCollapsed, "검색 바 미닫힘");
|
|
Assert.True(ok.toolbarHidden, "전체화면에서 크롬 미숨김");
|
|
Assert.True(ok.toolbarBack, "전체화면 복원 실패");
|
|
Assert.True(ok.compactRowZero, "컴팩트 모드에서 크롬 행이 숨겨지지 않음");
|
|
Assert.True(ok.compactRowBack, "컴팩트 모드 해제 후 크롬 행 미복원");
|
|
Assert.True(ok.notesOpen, "노트 패널 미열림");
|
|
Assert.True(ok.notesCount == 1, $"노트 추가 실패: {ok.notesCount}");
|
|
Assert.True(ok.archivedCount >= 1 && ok.archivedHasUrl, $"탭 아카이브 미기록: {ok.archivedCount}");
|
|
Assert.Equal(Paca.App.Browser.Features.PageFilter.Grayscale, ok.filterSaved);
|
|
}
|
|
finally
|
|
{
|
|
Environment.SetEnvironmentVariable("VD_DATA_DIR", null);
|
|
try { Directory.Delete(dataDir, true); } catch { }
|
|
}
|
|
}
|
|
|
|
private static Task WaitUntilNavCompleted(Microsoft.Web.WebView2.Core.CoreWebView2 cv)
|
|
{
|
|
var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
|
|
EventHandler<Microsoft.Web.WebView2.Core.CoreWebView2NavigationCompletedEventArgs>? h = null;
|
|
h = (_, _) => { cv.NavigationCompleted -= h; tcs.TrySetResult(); };
|
|
cv.NavigationCompleted += h;
|
|
return tcs.Task.WaitAsync(TimeSpan.FromSeconds(15));
|
|
}
|
|
}
|