feat: refresh workspace header

This commit is contained in:
2026-07-21 10:07:58 +09:00
parent 15ad9934a9
commit d9b477e543
5 changed files with 292 additions and 34 deletions

View File

@@ -87,3 +87,28 @@ test("dry-run mode reads as information and clipped status keeps its full toolti
assert.match(styles, /\.connection-state\.dry-run:not\(\.outcome-unknown\)\s*\{/);
assert.match(playout, /status\.title = status\.textContent/);
});
test("workspace header uses a modern semantic lockup without changing native status text", () => {
assert.match(markup,
/class="brand"[^>]*role="img"[^>]*aria-label="매일경제TV VRi"[\s\S]*?class="brand-symbol"[\s\S]*?<svg/);
assert.match(markup,
/class="workspace-heading"[\s\S]*?class="workspace-heading-icon"[\s\S]*?<div class="workspace-heading-copy">[\s\S]*?<small>현재 작업<\/small>[\s\S]*?id="workspace-title"/);
assert.match(markup,
/class="playout-connection-summary"[\s\S]*?<small>송출 연결<\/small>[\s\S]*?<strong>Tornado2<\/strong>[\s\S]*?id="playout-connection-state"/);
assert.match(markup,
/id="playout-connection-state"[^>]*role="status"[^>]*aria-label="Tornado2 연결 상태"[^>]*aria-live="polite"[^>]*aria-atomic="true">미연결<\/div>/);
assert.match(styles,
/\.workspace-header\s*\{[^}]*radial-gradient[\s\S]*?linear-gradient/);
assert.match(styles, /\.workspace-header::before\s*\{/);
assert.match(styles, /\.playlist-heading::before\s*\{/);
assert.match(styles, /\.connection-state::before\s*\{/);
assert.match(styles,
/\.playout-connection-copy small\s*\{[^}]*color:\s*var\(--ui-text-muted\)/);
assert.match(styles, /\.connection-state\.connected::before\s*\{/);
assert.match(styles,
/\.connection-state\.dry-run:not\(\.outcome-unknown\)::before\s*\{/);
assert.match(styles,
/\.workspace-surface\s*\{[^}]*grid-template-rows:\s*66px minmax\(0, 1fr\)/);
assert.match(playout,
/const nextConnectionText = connectionLabel\(playout\);[\s\S]*?if \(connection\.textContent !== nextConnectionText\)[\s\S]*?connection\.textContent = nextConnectionText/);
});

View File

@@ -171,6 +171,44 @@ public sealed class LegacyWorkspaceLayoutContractTests
Markup);
}
[Fact]
public void WorkspaceHeaderUsesModernSemanticLockupAndStableNativeStatusTarget()
{
Assert.Matches(
@"class=""brand""[^>]*role=""img""[^>]*aria-label=""매일경제TV VRi""[\s\S]*?" +
@"class=""brand-symbol""[\s\S]*?<svg",
Markup);
Assert.Matches(
@"class=""workspace-heading""[\s\S]*?class=""workspace-heading-icon""" +
@"[\s\S]*?<div class=""workspace-heading-copy"">[\s\S]*?" +
@"<small>현재 작업</small>[\s\S]*?id=""workspace-title""",
Markup);
Assert.Matches(
@"class=""playout-connection-summary""[\s\S]*?<small>송출 연결</small>" +
@"[\s\S]*?<strong>Tornado2</strong>[\s\S]*?id=""playout-connection-state""",
Markup);
Assert.Matches(
@"id=""playout-connection-state""[^>]*role=""status""" +
@"[^>]*aria-label=""Tornado2 연결 상태""[^>]*aria-live=""polite""" +
@"[^>]*aria-atomic=""true"">미연결</div>",
Markup);
Assert.Contains(".workspace-header::before", Styles, StringComparison.Ordinal);
Assert.Contains(".playlist-heading::before", Styles, StringComparison.Ordinal);
Assert.Contains(".connection-state::before", Styles, StringComparison.Ordinal);
Assert.Matches(
@"\.playout-connection-copy small\s*\{[^}]*color:\s*var\(--ui-text-muted\)",
Styles);
Assert.Contains(".connection-state.connected::before", Styles, StringComparison.Ordinal);
Assert.Contains(
".connection-state.dry-run:not(.outcome-unknown)::before",
Styles,
StringComparison.Ordinal);
Assert.Contains(
"if (connection.textContent !== nextConnectionText)",
File.ReadAllText(Path.Combine(WebRoot, "playout-ui.js")),
StringComparison.Ordinal);
}
[Fact]
public void NavigationChangesPresentationWithoutNativeOrStoredState()
{