feat: expose graphic screens in sidebar

This commit is contained in:
2026-07-21 09:45:12 +09:00
parent 44a7d90413
commit 15ad9934a9
11 changed files with 1044 additions and 117 deletions

View File

@@ -17,25 +17,56 @@ public sealed class LegacyWorkspaceLayoutContractTests
Path.Combine(WebRoot, "workspace-navigation.js"));
[Fact]
public void ShellUsesSwitchableWorkspaceBesidePersistentSchedule()
public void ShellUsesSidebarScreensBesidePersistentSchedule()
{
var workspaceStart = Markup.IndexOf("id=\"workspace-region\"", StringComparison.Ordinal);
var navigationStart = Markup.IndexOf("id=\"workspace-navigation\"", StringComparison.Ordinal);
var marketStart = Markup.IndexOf("id=\"market-tabs\"", StringComparison.Ordinal);
var settingsTabStart = Markup.IndexOf("id=\"workspace-settings-tab\"", StringComparison.Ordinal);
var stockStart = Markup.IndexOf("id=\"stock-workspace\"", StringComparison.Ordinal);
var catalogStart = Markup.IndexOf("id=\"catalog-workspace\"", StringComparison.Ordinal);
var settingsStart = Markup.IndexOf("id=\"settings-workspace\"", StringComparison.Ordinal);
var scheduleStart = Markup.IndexOf("class=\"playlist-panel\"", StringComparison.Ordinal);
Assert.True(workspaceStart >= 0);
Assert.True(stockStart > workspaceStart);
Assert.True(navigationStart > workspaceStart);
Assert.True(marketStart > navigationStart);
Assert.True(settingsTabStart > marketStart);
Assert.True(stockStart > settingsTabStart);
Assert.True(catalogStart > stockStart);
Assert.True(scheduleStart > catalogStart);
Assert.True(settingsStart > catalogStart);
Assert.True(scheduleStart > settingsStart);
Assert.Matches(
@"<\/section>\s*<\/div>\s*<\/section>\s*<\/section>\s*<section class=""playlist-panel""",
Markup);
Assert.Matches("id=\"catalog-workspace\"[^>]*hidden inert", Markup);
Assert.Matches("id=\"settings-workspace\"[^>]*hidden inert", Markup);
Assert.Contains("<small>항상 표시</small><h2>송출 스케줄</h2>", Markup,
StringComparison.Ordinal);
}
[Fact]
public void SidebarOwnsEachNativeMarketButtonAndKeepsSettingsOutsideTheirOrder()
{
var marketStart = Markup.IndexOf("<div id=\"market-tabs\"", StringComparison.Ordinal);
var marketEnd = Markup.IndexOf("</div>", marketStart, StringComparison.Ordinal);
Assert.True(marketStart >= 0 && marketEnd > marketStart);
var marketMarkup = Markup[marketStart..marketEnd];
var expected = new[]
{
"overseas", "exchange", "index", "kospiIndustry", "kosdaqIndustry",
"comparison", "theme", "overseasStocks", "expert", "tradingHalt"
};
var actual = Regex.Matches(marketMarkup, "data-tab-id=\"([^\"]+)\"")
.Select(match => match.Groups[1].Value)
.ToArray();
Assert.Equal(expected, actual);
Assert.Equal(expected.Length, Regex.Matches(marketMarkup, "<button\\b").Count);
Assert.DoesNotContain("workspace-settings-tab", marketMarkup, StringComparison.Ordinal);
Assert.Contains("workspace-nav-label", marketMarkup, StringComparison.Ordinal);
}
[Fact]
public void WorkAndScheduleUseResponsiveTwoToOneColumns()
{
@@ -43,6 +74,13 @@ public sealed class LegacyWorkspaceLayoutContractTests
"grid-template-columns: minmax(900px, 2fr) minmax(600px, 1fr);",
Styles,
StringComparison.Ordinal);
Assert.Contains(
"grid-template-rows: 66px minmax(0, 1fr) auto;",
Styles,
StringComparison.Ordinal);
Assert.Contains(".workspace-nav-footer", Styles, StringComparison.Ordinal);
Assert.Contains(".workspace-navigation .market-tabs button", Styles,
StringComparison.Ordinal);
Assert.Matches(
new Regex(
@"\.playlist-toolbar\s*\{[^}]*flex-wrap:\s*wrap",
@@ -55,6 +93,28 @@ public sealed class LegacyWorkspaceLayoutContractTests
Styles);
}
[Fact]
public void SidebarIsOneLabelledAndFullyControlledNavigationRegion()
{
Assert.Matches(
"id=\"workspace-navigation\"[^>]*role=\"navigation\"[^>]*aria-label=",
Markup);
Assert.Matches(
"id=\"workspace-nav-toggle\"[^>]*aria-expanded=\"true\"[\\s\\S]*?" +
"aria-controls=\"workspace-nav-items workspace-nav-footer\"",
Markup);
Assert.Matches(
"id=\"workspace-nav-items\"[^>]*role=\"group\"[^>]*aria-label=",
Markup);
Assert.Matches(
"id=\"market-tabs\"[^>]*role=\"group\"[^>]*aria-label=",
Markup);
Assert.Contains(
"id=\"workspace-nav-footer\" class=\"workspace-nav-footer\"",
Markup,
StringComparison.Ordinal);
}
[Fact]
public void ModernOperatorThemePreservesAccessibleAndSemanticStates()
{
@@ -119,6 +179,14 @@ public sealed class LegacyWorkspaceLayoutContractTests
"entry.view.toggleAttribute(\"inert\", !isCurrent)",
Navigation,
StringComparison.Ordinal);
Assert.Contains("settingsTab.addEventListener(\"click\"", Navigation,
StringComparison.Ordinal);
Assert.Contains("syncMarket(button.dataset.tabId)", Navigation,
StringComparison.Ordinal);
Assert.Contains("menuButton.click()", Navigation, StringComparison.Ordinal);
Assert.Contains("pendingKeyboardMarketTabId", Navigation, StringComparison.Ordinal);
Assert.Contains("pendingButton.focus()", Navigation, StringComparison.Ordinal);
Assert.Contains("LegacyWorkspaceNavigation", Navigation, StringComparison.Ordinal);
Assert.Contains("nav-collapsed", Navigation, StringComparison.Ordinal);
Assert.DoesNotContain("postMessage", Navigation, StringComparison.Ordinal);
Assert.DoesNotContain("localStorage", Navigation, StringComparison.Ordinal);