Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions e2e/tests/pages.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ test('public reading page displays transcript and opens a working text export',
await expect(ossBar.locator('a[href="https://github.com/zlxlabs/VideoTranscriptAPI"]')).toBeVisible();
await expect(ossBar.locator('a[href="https://x.com/bylixing"]')).toBeVisible();

// Assert oss-bar does not overflow in 375px mobile viewport
await page.setViewportSize({ width: 375, height: 667 });
await expect(ossBar).toContainText('张立行');
const isNotOverflowing = await ossBar.evaluate((el) => el.scrollWidth <= el.clientWidth);
expect(isNotOverflowing).toBe(true);
await page.setViewportSize({ width: 1280, height: 720 });

await expect(page.locator('#calibrated-content-block')).toContainText(
'隔离浏览器夹具中的正文,验证公开阅读与导出。');
const exportMenu = page.locator('.export-links-details');
Expand Down
48 changes: 8 additions & 40 deletions src/web/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -877,23 +877,6 @@
transition: background 0.3s ease, border-color 0.3s ease, color 0.3s ease;
}

.oss-bar-desc {
display: inline-flex;
align-items: center;
}

.oss-bar-desc-desktop {
display: inline;
}

.oss-bar-desc-mobile {
display: none;
}

.oss-bar-author-label {
display: inline;
}

.oss-bar-sep {
opacity: 0.6;
user-select: none;
Expand Down Expand Up @@ -936,18 +919,6 @@
display: none;
}

.oss-bar-desc-desktop {
display: none;
}

.oss-bar-desc-mobile {
display: inline;
}

.oss-bar-author-label {
display: none;
}

.oss-bar-link {
min-height: 32px;
display: inline-flex;
Expand Down Expand Up @@ -1135,25 +1106,22 @@
</head>
<body>
<div class="container">
<div class="oss-bar" role="banner" aria-label="开源项目信息">
<span class="oss-bar-desc">
<span class="oss-bar-desc-desktop">本页由开源项目 VideoTranscriptAPI 生成,可自行部署</span>
<span class="oss-bar-desc-mobile">开源项目</span>
</span>
<span class="oss-bar-sep" aria-hidden="true">·</span>
<a href="https://github.com/zlxlabs/VideoTranscriptAPI" class="oss-bar-link" target="_blank" rel="noopener" aria-label="GitHub 开源仓库">
<div class="oss-bar" aria-label="开源项目信息">
<span>由开源项目 </span>
<a href="https://github.com/zlxlabs/VideoTranscriptAPI" class="oss-bar-link" target="_blank" rel="noopener" title="开源,可自行部署" aria-label="GitHub 开源仓库 VideoTranscriptAPI">
<svg class="oss-bar-icon" viewBox="0 0 16 16" width="14" height="14" fill="currentColor" aria-hidden="true">
<path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"/>
</svg>
<span>GitHub ↗</span>
<span>VideoTranscriptAPI</span>
</a>
<span> 生成</span>
<span class="oss-bar-sep" aria-hidden="true">·</span>
<a href="https://x.com/bylixing" class="oss-bar-link" target="_blank" rel="noopener" aria-label="作者 X 账号">
<span class="oss-bar-author-label">作者 </span>
<span>by </span>
<a href="https://x.com/bylixing" class="oss-bar-link" target="_blank" rel="noopener" title="在 X 上关注 @bylixing" aria-label="作者张立行的 X 账号 @bylixing">
<svg class="oss-bar-icon" viewBox="0 0 24 24" width="14" height="14" fill="currentColor" aria-hidden="true">
<path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 24.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/>
</svg>
<span>@bylixing</span>
<span>张立行</span>
</a>
</div>
<div class="header">
Expand Down
72 changes: 60 additions & 12 deletions tests/unit/web/test_oss_bar.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,13 @@ def test_container_encloses_oss_bar_as_first_child(self):
snippet = html[container_idx + len(container_tag):bar_idx].strip()
assert snippet == "<div", f"Expected only div tag before class=\"oss-bar\", got: {snippet!r}"

def test_oss_bar_has_no_role_banner(self):
html = _render_transcript()
bar_opening = re.search(r'<div[^>]*class="oss-bar"[^>]*>', html)
assert bar_opening is not None
assert 'role="banner"' not in bar_opening.group(0), "Expected .oss-bar not to have role=\"banner\""
assert 'aria-label="开源项目信息"' in bar_opening.group(0)


class TestTopOssBarLinkAttributesAndIcons:
"""Verify link security attributes, accessibility labels, and inline SVGs."""
Expand All @@ -112,7 +119,8 @@ def test_links_security_and_accessibility_attributes(self):
gh_tag = match_gh.group(0)
assert 'target="_blank"' in gh_tag
assert 'rel="noopener"' in gh_tag
assert "aria-label=" in gh_tag
assert 'title="开源,可自行部署"' in gh_tag
assert 'aria-label="GitHub 开源仓库 VideoTranscriptAPI"' in gh_tag

x_pattern = re.compile(
r'<a[^>]+href="' + re.escape(X_URL) + r'"[^>]*>', re.IGNORECASE
Expand All @@ -122,7 +130,30 @@ def test_links_security_and_accessibility_attributes(self):
x_tag = match_x.group(0)
assert 'target="_blank"' in x_tag
assert 'rel="noopener"' in x_tag
assert "aria-label=" in x_tag
assert 'title="在 X 上关注 @bylixing"' in x_tag
assert 'aria-label="作者张立行的 X 账号 @bylixing"' in x_tag

def test_link_inner_visible_text(self):
html = _render_transcript()
gh_match = re.search(
r'<a[^>]+href="' + re.escape(GITHUB_URL) + r'"[^>]*>(.*?)</a>',
html,
re.DOTALL,
)
assert gh_match is not None, "GitHub link not found"
gh_inner = re.sub(r'<svg.*?</svg>', '', gh_match.group(1), flags=re.DOTALL)
gh_text = re.sub(r'<[^>]+>', '', gh_inner).strip()
assert gh_text == "VideoTranscriptAPI"

x_match = re.search(
r'<a[^>]+href="' + re.escape(X_URL) + r'"[^>]*>(.*?)</a>',
html,
re.DOTALL,
)
assert x_match is not None, "X link not found"
x_inner = re.sub(r'<svg.*?</svg>', '', x_match.group(1), flags=re.DOTALL)
x_text = re.sub(r'<[^>]+>', '', x_inner).strip()
assert x_text == "张立行"

def test_inline_svg_icons_used_without_emojis(self):
html = _render_transcript()
Expand All @@ -136,23 +167,40 @@ def test_inline_svg_icons_used_without_emojis(self):


class TestTopOssBarResponsiveStyling:
"""Ensure media query <=640px and desktop/mobile text classes exist."""
"""Ensure unified visible text across viewports and responsive touch targets."""

def test_desktop_and_mobile_text_elements_present(self):
def test_unified_oss_bar_visible_text(self):
html = _render_transcript()
match = re.search(r'<div[^>]*class="oss-bar"[^>]*>(.*?)</div>', html, re.DOTALL)
assert match is not None, "oss-bar element not found"
without_svg = re.sub(r'<svg.*?</svg>', '', match.group(1), flags=re.DOTALL)
visible_text = re.sub(r'<[^>]+>', '', without_svg)
normalized = re.sub(r'\s+', ' ', visible_text).strip()
assert normalized == "由开源项目 VideoTranscriptAPI 生成 · by 张立行"

def test_no_legacy_text_or_desktop_mobile_switching_classes(self):
html = _render_transcript()
assert "oss-bar-desc-desktop" in html
assert "本页由开源项目 VideoTranscriptAPI 生成,可自行部署" in html
assert "oss-bar-desc-mobile" in html
assert "开源项目" in html
assert "GitHub ↗" in html
assert "@bylixing" in html
match = re.search(r'<div[^>]*class="oss-bar"[^>]*>(.*?)</div>', html, re.DOTALL)
assert match is not None, "oss-bar element not found"
without_svg = re.sub(r'<svg.*?</svg>', '', match.group(1), flags=re.DOTALL)
visible_text = re.sub(r'<[^>]+>', '', without_svg)

assert "@bylixing" not in visible_text
assert "GitHub ↗" not in visible_text
assert "本页由开源项目" not in visible_text
assert "可自行部署" not in visible_text

for class_name in ["oss-bar-desc-desktop", "oss-bar-desc-mobile", "oss-bar-author-label"]:
assert class_name not in html

def test_media_query_and_touch_target_in_styles(self):
base_html = (TEMPLATES_DIR / "base.html").read_text(encoding="utf-8")
assert "@media (max-width: 640px)" in base_html
assert ".oss-bar-desc-desktop" in base_html
assert ".oss-bar-desc-mobile" in base_html
assert "min-height: 32px" in base_html
assert "white-space: nowrap" in base_html
assert ".oss-bar-desc-desktop" not in base_html
assert ".oss-bar-desc-mobile" not in base_html
assert ".oss-bar-author-label" not in base_html


class TestNoLegacyRepoUrlsInWebAssets:
Expand Down
Loading