Some checks failed
Release & Docker / release (push) Has been cancelled
#3728 (@rodboev): markdown tables sortable+filterable on desktop, suppressed <=640px so mobile is unchanged. UX-approved by Nathan via Telegram. Full suite 8234, CI 11/11, live-driven. Co-authored-by: rodboev <rodboev@users.noreply.github.com>
93 lines
4.1 KiB
Python
93 lines
4.1 KiB
Python
import re
|
|
from pathlib import Path
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
|
|
|
|
def _read_static(name):
|
|
return (ROOT / "static" / name).read_text(encoding="utf-8")
|
|
|
|
|
|
def _locale_blocks():
|
|
text = _read_static("i18n.js")
|
|
matches = list(re.finditer(r"^ '?([A-Za-z]{2}(?:-[A-Za-z]+)?)'?: \{", text, re.M))
|
|
assert matches, "could not find locale blocks"
|
|
blocks = {}
|
|
for idx, match in enumerate(matches):
|
|
end = matches[idx + 1].start() if idx + 1 < len(matches) else text.index("\n};", match.end())
|
|
blocks[match.group(1)] = text[match.end():end]
|
|
return blocks
|
|
|
|
|
|
def test_markdown_table_enhancer_is_registered_and_invoked_after_render_paths():
|
|
messages = _read_static("messages.js")
|
|
|
|
assert "function enhanceMarkdownTables(root)" in messages
|
|
assert "window.enhanceMarkdownTables=enhanceMarkdownTables" in messages
|
|
assert "function _wireMarkdownTableEnhancer()" in messages
|
|
assert "window.renderMessages=function(...args)" in messages
|
|
assert "enhanceMarkdownTables(inner)" in messages
|
|
|
|
smd_end = messages[messages.index("function _smdEndParser()"):messages.index("function _scheduleStreamingKatex()")]
|
|
assert "_sanitizeSmdLinks(assistantBody);enhanceMarkdownTables(assistantBody);" in smd_end
|
|
|
|
|
|
def test_markdown_table_enhancement_is_idempotent_and_message_scoped():
|
|
messages = _read_static("messages.js")
|
|
helper = messages[messages.index("function enhanceMarkdownTables(root)"):messages.index("function _markdownTableText")]
|
|
|
|
assert ".msg-body table:not([data-markdown-table-enhanced])" in helper
|
|
assert "data-markdown-table-enhanced" in helper
|
|
assert "table.setAttribute('data-markdown-table-enhanced','1')" in helper
|
|
assert ".csv-table-wrap" in helper
|
|
|
|
|
|
def test_markdown_table_sorting_uses_accessible_buttons_and_stable_rows():
|
|
messages = _read_static("messages.js")
|
|
helper = messages[messages.index("function enhanceMarkdownTables(root)"):messages.index("function _markdownTableText")]
|
|
|
|
assert "document.createElement('button')" in helper
|
|
assert "button.type='button'" in helper
|
|
assert "const columnName=_markdownTableText(cell.textContent)||String(colIdx+1)" in helper
|
|
assert "const columnSortLabel=`${sortLabel}: ${columnName}`" in helper
|
|
assert "button.setAttribute('aria-label',columnSortLabel)" in helper
|
|
assert "button.title=columnSortLabel" in helper
|
|
assert "cell.setAttribute('aria-sort','none')" in helper
|
|
assert "other.setAttribute('aria-sort','none')" in helper
|
|
assert "cell.setAttribute('aria-sort',nextDir==='asc'?'ascending':'descending')" in helper
|
|
assert "row.dataset.markdownTableOriginalIndex=String(idx)" in helper
|
|
assert "localeCompare(bv,undefined,{numeric:true,sensitivity:'base'})" in helper
|
|
assert "return ai-bi" in helper
|
|
|
|
|
|
def test_markdown_table_filter_is_gated_to_multi_row_tables_and_preserves_rows():
|
|
messages = _read_static("messages.js")
|
|
helper = messages[messages.index("function enhanceMarkdownTables(root)"):messages.index("function _markdownTableText")]
|
|
|
|
assert "if(bodyRows.length>=4&&table.parentElement)" in helper
|
|
assert "filter.type='search'" in helper
|
|
assert "filter.placeholder=filterLabel" in helper
|
|
assert "filter.setAttribute('aria-label',filterLabel)" in helper
|
|
assert "row.hidden=!!query" in helper
|
|
assert "body.appendChild(row)" in helper
|
|
|
|
|
|
def test_markdown_table_styles_keep_controls_compact():
|
|
style = _read_static("style.css")
|
|
|
|
assert ".markdown-table-filter" in style
|
|
assert "width:min(260px,100%)" in style
|
|
assert ".markdown-table-sort{display:flex" in style
|
|
assert "min-height:20px" in style
|
|
assert ".msg-body th[aria-sort=\"ascending\"]" in style
|
|
assert ".msg-body th[aria-sort=\"descending\"]" in style
|
|
|
|
|
|
def test_markdown_table_i18n_keys_are_present_in_every_locale():
|
|
assert "zh-Hant" in _locale_blocks()
|
|
for locale, block in _locale_blocks().items():
|
|
keys = set(re.findall(r"^\s*([A-Za-z0-9_]+):", block, re.M))
|
|
assert "markdown_table_filter" in keys, f"{locale} missing markdown_table_filter"
|
|
assert "markdown_table_sort_column" in keys, f"{locale} missing markdown_table_sort_column"
|