#41 m6/cards2
Patch
src/build.rs+35 −22--- a/src/build.rs+++ b/src/build.rs@@ -579,13 +579,13 @@ pub fn file_table_html(579579 history: &std::collections::BTreeMap<String, (String, String)>,580580 ) -> String {581581 let mut out = String::from(582- "<div class=\"table-scroll\"><table class=\"file-table\">\n\582+ "<div class=\"table-scroll file-scroll\"><table class=\"file-table\">\n\583583 <thead><tr><th>Name</th><th>Last commit</th><th>Age</th></tr></thead>\n<tbody>\n",584584 );585585 if let Some((href, label)) = parent {586586 out.push_str(&format!(587- "<tr class=\"parent\"><td class=\"trunc\" data-label=\"Name\" title=\"{}\"><a href=\"{}\">{}</a></td>\588- <td class=\"trunc trunc-message\" data-label=\"Last commit\" title=\"\"></td><td class=\"trunc\" data-label=\"Age\" title=\"\"></td></tr>\n",587+ "<tr class=\"parent\"><td class=\"trunc\" title=\"{}\"><a href=\"{}\">{}</a></td>\588+ <td class=\"trunc trunc-message\" title=\"\"></td><td class=\"trunc\" title=\"\"></td></tr>\n",589589 esc(label),590590 esc(href),591591 esc(label)@@ -601,8 +601,8 @@ pub fn file_table_html(601601 let msg_short = truncate_msg(&msg);602602 if e.is_dir {603603 out.push_str(&format!(604- "<tr class=\"dir\"><td class=\"trunc\" data-label=\"Name\" title=\"{}\"><a href=\"/files/{}.html\">{}/</a></td>\605- <td class=\"title trunc trunc-message\" data-label=\"Last commit\" title=\"{}\">{}</td><td class=\"trunc\" data-label=\"Age\" title=\"{}\">{}</td></tr>\n",604+ "<tr class=\"dir\"><td class=\"trunc\" title=\"{}\"><a href=\"/files/{}.html\">{}/</a></td>\605+ <td class=\"title trunc trunc-message\" title=\"{}\">{}</td><td class=\"trunc\" title=\"{}\">{}</td></tr>\n",606606 esc(&e.name),607607 href_esc(&full),608608 esc(&e.name),@@ -613,8 +613,8 @@ pub fn file_table_html(613613 ));614614 } else {615615 out.push_str(&format!(616- "<tr class=\"file\"><td class=\"trunc\" data-label=\"Name\" title=\"{}\"><a href=\"/files/{}.html\">{}</a></td>\617- <td class=\"title trunc trunc-message\" data-label=\"Last commit\" title=\"{}\">{}</td><td class=\"trunc\" data-label=\"Age\" title=\"{}\">{}</td></tr>\n",616+ "<tr class=\"file\"><td class=\"trunc\" title=\"{}\"><a href=\"/files/{}.html\">{}</a></td>\617+ <td class=\"title trunc trunc-message\" title=\"{}\">{}</td><td class=\"trunc\" title=\"{}\">{}</td></tr>\n",618618 esc(&e.name),619619 href_esc(&full),620620 esc(&e.name),@@ -1732,28 +1732,41 @@ mod tests {17321732 assert!(sub.contains("title=\""), "title attrs kept");17331733 }17341734 1735- /// m6/no-scroll (f0rge #39): file-table rows carry data-labels for cards.1735+ /// m6/cards2 (f0rge #46): file table stays a real table on all widths —1736+ /// no data-label card treatment, scroll wrapper kept, trunc + title kept.17361737 #[test]1737- fn file_table_cells_have_data_labels() {1738+ fn file_table_stays_table_no_card_labels() {17381739 let css = include_str!("../static/style.css");1739- assert!(css.contains("content:attr(data-label)"), "label rule");17401740 assert!(css.contains("@media (max-width:767px)"), "narrow query");1741+ assert!(1742+ css.contains(".table-scroll:not(.file-scroll)"),1743+ "cards scoped off file-scroll"1744+ );1745+ assert!(1746+ css.contains(".file-scroll{overflow-x:auto}"),1747+ "file-scroll keeps h-scroll on narrow"1748+ );17411749 let (_repo, out) = build_fixture();17421750 for page in ["index.html", "files/sub.html"] {17431751 let html = std::fs::read_to_string(out.join(page)).expect(page);1744- let tds = html.matches("<td").count();1745- assert!(tds > 0, "{page} has cells");1746- assert_eq!(1747- html.matches("data-label=").count(),1748- tds,1749- "{page}: every td labeled"1752+ assert!(1753+ html.contains(1754+ "<div class=\"table-scroll file-scroll\"><table class=\"file-table\">"1755+ ),1756+ "{page}: scroll wrapper kept"1757+ );1758+ assert!(!html.contains("data-label="), "{page}: no card labels");1759+ assert!(1760+ html.contains("<td class=\"title trunc trunc-message\""),1761+ "{page}: message cell trunc kept"1762+ );1763+ assert!(html.contains("title=\""), "{page}: title attrs kept");1764+ assert!(1765+ html.contains("<th>Name</th>")1766+ && html.contains("<th>Last commit</th>")1767+ && html.contains("<th>Age</th>"),1768+ "{page}: headers kept"17501769 );1751- for label in ["Name", "Last commit", "Age"] {1752- assert!(1753- html.contains(&format!("data-label=\"{label}\"")),1754- "{page}: label {label}"1755- );1756- }17571770 }17581771 }17591772
src/commits.rs+8 −4--- a/src/commits.rs+++ b/src/commits.rs@@ -40,15 +40,15 @@ pub fn render_loaded(4040 if log.is_empty() {4141 body.push_str("<p class=\"muted\">No commits yet.</p>\n");4242 } else {43- body.push_str("<div class=\"table-scroll\"><table>\n<thead><tr><th>sha</th><th>subject</th><th>author</th><th>date</th></tr></thead>\n<tbody>\n");43+ body.push_str("<div class=\"table-scroll\"><table>\n<thead><tr><th>subject</th><th>sha</th><th>author</th><th>date</th></tr></thead>\n<tbody>\n");4444 for c in log {4545 body.push_str(&format!(46- "<tr><td class=\"sha trunc trunc-sha\" data-label=\"sha\" title=\"{}\"><a href=\"/commit/{}.html\"><code>{}</code></a></td><td class=\"title trunc trunc-subject\" data-label=\"subject\" title=\"{}\">{}</td><td class=\"trunc trunc-author\" data-label=\"author\" title=\"{}\">{}</td><td class=\"trunc\" data-label=\"date\" title=\"{}\">{}</td></tr>\n",46+ "<tr><td class=\"title trunc trunc-subject\" data-label=\"subject\" title=\"{}\">{}</td><td class=\"sha trunc trunc-sha\" data-label=\"sha\" title=\"{}\"><a href=\"/commit/{}.html\"><code>{}</code></a></td><td class=\"trunc trunc-author\" data-label=\"author\" title=\"{}\">{}</td><td class=\"trunc\" data-label=\"date\" title=\"{}\">{}</td></tr>\n",47+ esc(&c.subject),48+ esc(&c.subject),4749 esc(&c.sha),4850 esc(&c.sha),4951 esc(short_sha(&c.sha)),50- esc(&c.subject),51- esc(&c.subject),5252 esc(&c.author),5353 esc(&c.author),5454 esc(&c.date),@@ -423,5 +423,9 @@ mod tests {423423 "label {label}"424424 );425425 }426+ // m6/cards2 (f0rge #47): card DOM order is subject-first.427+ let subj = list.find("data-label=\"subject\"").expect("subject cell");428+ let sha = list.find("data-label=\"sha\"").expect("sha cell");429+ assert!(subj < sha, "card DOM: subject precedes sha");426430 }427431 }
src/forge.rs+41 −6--- a/src/forge.rs+++ b/src/forge.rs@@ -998,10 +998,10 @@ fn render_issues_index(998998 if data.issues.is_empty() {999999 body.push_str("<p class=\"muted\">No issues yet. <a href=\"/new-issue.html\">Suggest one</a> — no account needed.</p>\n");10001000 } else {1001- body.push_str("<div class=\"table-scroll\"><table>\n<thead><tr><th>#</th><th>title</th><th>state</th><th>comments</th><th>created</th></tr></thead>\n<tbody>\n");1001+ body.push_str("<div class=\"table-scroll\"><table>\n<thead><tr><th>title</th><th>#</th><th>state</th><th>comments</th><th>created</th></tr></thead>\n<tbody>\n");10021002 for issue in &data.issues {10031003 body.push_str(&format!(1004- "<tr><td class=\"num trunc\" data-label=\"#\" title=\"{n}\">{n}</td><td class=\"title trunc trunc-title\" data-label=\"title\" title=\"{title}\"><a href=\"/issues/{id}.html\">{title}</a></td><td class=\"trunc\" data-label=\"state\" title=\"{state}\">{state}</td><td class=\"trunc\" data-label=\"comments\" title=\"{comments}\">{comments}</td><td class=\"trunc\" data-label=\"created\" title=\"{created}\">{created}</td></tr>\n",1004+ "<tr><td class=\"title trunc trunc-title\" data-label=\"title\" title=\"{title}\"><a href=\"/issues/{id}.html\">{title}</a></td><td class=\"num trunc\" data-label=\"#\" title=\"{n}\">{n}</td><td class=\"trunc\" data-label=\"state\" title=\"{state}\">{state}</td><td class=\"trunc\" data-label=\"comments\" title=\"{comments}\">{comments}</td><td class=\"trunc\" data-label=\"created\" title=\"{created}\">{created}</td></tr>\n",10051005 n = issue.number,10061006 id = esc(&issue.id),10071007 title = esc(&issue.title),@@ -1059,14 +1059,14 @@ fn render_pulls_index(10591059 if prs.is_empty() {10601060 body.push_str("<p class=\"muted\">No pull requests yet. <a href=\"/new-pr.html\">Suggest one</a> — no account needed.</p>\n");10611061 } else {1062- body.push_str("<div class=\"table-scroll\"><table>\n<thead><tr><th>#</th><th>title</th><th>state</th><th>head→base</th><th>created</th></tr></thead>\n<tbody>\n");1062+ body.push_str("<div class=\"table-scroll\"><table>\n<thead><tr><th>title</th><th>#</th><th>state</th><th>head→base</th><th>created</th></tr></thead>\n<tbody>\n");10631063 for pr in prs {10641064 let lanes = format!("{}→{}", esc(&pr.head), esc(&pr.base));10651065 let lanes_plain = format!("{}→{}", pr.head, pr.base);10661066 let draft = if pr.draft { " draft" } else { "" };10671067 let full_title = format!("{}{}", pr.title, draft);10681068 body.push_str(&format!(1069- "<tr><td class=\"num trunc\" data-label=\"#\" title=\"{n}\">{n}</td><td class=\"title trunc trunc-title\" data-label=\"title\" title=\"{full}\"><a href=\"/pulls/{id}.html\">{title}</a>{draft}</td><td class=\"trunc\" data-label=\"state\" title=\"{state}\">{state}</td><td class=\"trunc\" data-label=\"head→base\" title=\"{lanes_title}\"><code>{lanes}</code></td><td class=\"trunc\" data-label=\"created\" title=\"{created}\">{created}</td></tr>\n",1069+ "<tr><td class=\"title trunc trunc-title\" data-label=\"title\" title=\"{full}\"><a href=\"/pulls/{id}.html\">{title}</a>{draft}</td><td class=\"num trunc\" data-label=\"#\" title=\"{n}\">{n}</td><td class=\"trunc\" data-label=\"state\" title=\"{state}\">{state}</td><td class=\"trunc\" data-label=\"head→base\" title=\"{lanes_title}\"><code>{lanes}</code></td><td class=\"trunc\" data-label=\"created\" title=\"{created}\">{created}</td></tr>\n",10701070 n = pr.number,10711071 id = esc(&pr.id),10721072 title = esc(&pr.title),@@ -1823,11 +1823,19 @@ mod tests {18231823 css.contains("content:attr(data-label)"),18241824 "label via ::before"18251825 );1826- assert!(css.contains(".table-scroll td::before"), "label rule");18271826 assert!(1828- css.contains(".table-scroll td.title::before"),1827+ css.contains(".table-scroll:not(.file-scroll) td::before"),1828+ "label rule"1829+ );1830+ assert!(1831+ css.contains(".table-scroll:not(.file-scroll) td.title::before"),18291832 "title leads card"18301833 );1834+ // m6/cards2 (f0rge #46): file table exempt from the card reflow.1835+ assert!(1836+ css.contains(".file-scroll{overflow-x:auto}"),1837+ "file table keeps h-scroll on narrow"1838+ );18311839 assert!(18321840 css.contains("display:block") && css.contains("display:flex"),18331841 "card layout"@@ -1894,8 +1902,35 @@ mod tests {18941902 );18951903 }18961904 }1905+ // m6/cards2 (f0rge #47): card DOM order is title-first via template1906+ // cell order (no CSS order hacks) — desktop column headers match.1907+ for (page, first, second) in [1908+ (1909+ "issues/index.html",1910+ "data-label=\"title\"",1911+ "data-label=\"#\"",1912+ ),1913+ (1914+ "pulls/index.html",1915+ "data-label=\"title\"",1916+ "data-label=\"#\"",1917+ ),1918+ (1919+ "ci/index.html",1920+ "data-label=\"step\"",1921+ "data-label=\"exit\"",1922+ ),1923+ ] {1924+ let html = std::fs::read_to_string(out.join(page)).expect(page);1925+ let a = html.find(first).expect("first cell");1926+ let b = html.find(second).expect("second cell");1927+ assert!(a < b, "{page}: card DOM title precedes meta");1928+ }18971929 let tasks = std::fs::read_to_string(out.join("tasks/index.html")).expect("tasks");18981930 assert!(!tasks.contains("table-scroll"), "tasks: no scroll wrapper");1931+ let title_pos = tasks.find("Card task").expect("task title");1932+ let meta_pos = tasks.find("<code>cccccccc").expect("task meta");1933+ assert!(title_pos < meta_pos, "tasks: title precedes meta");18991934 assert!(tasks.contains("todo (1)"), "tasks group kept");19001935 let issues = std::fs::read_to_string(out.join("issues/index.html")).expect("issues");19011936 assert!(
src/releases.rs+6 −2--- a/src/releases.rs+++ b/src/releases.rs@@ -395,10 +395,10 @@ pub fn render_loaded(395395 if releases.is_empty() {396396 body.push_str("<p class=\"muted\">No releases yet.</p>\n");397397 } else {398- body.push_str("<div class=\"table-scroll\"><table>\n<thead><tr><th>version</th><th>title</th><th>created</th><th>artifacts</th></tr></thead>\n<tbody>\n");398+ body.push_str("<div class=\"table-scroll\"><table>\n<thead><tr><th>title</th><th>version</th><th>created</th><th>artifacts</th></tr></thead>\n<tbody>\n");399399 for rel in releases {400400 body.push_str(&format!(401- "<tr><td class=\"trunc\" data-label=\"version\" title=\"{v}\"><a href=\"/releases/{v}.html\">{ve}</a></td><td class=\"title trunc trunc-title\" data-label=\"title\" title=\"{t}\">{t}</td><td class=\"trunc\" data-label=\"created\" title=\"{c}\">{c}</td><td class=\"trunc\" data-label=\"artifacts\" title=\"{n}\">{n}</td></tr>\n",401+ "<tr><td class=\"title trunc trunc-title\" data-label=\"title\" title=\"{t}\">{t}</td><td class=\"trunc\" data-label=\"version\" title=\"{v}\"><a href=\"/releases/{v}.html\">{ve}</a></td><td class=\"trunc\" data-label=\"created\" title=\"{c}\">{c}</td><td class=\"trunc\" data-label=\"artifacts\" title=\"{n}\">{n}</td></tr>\n",402402 v = esc(&rel.version),403403 ve = esc(&rel.version),404404 t = esc(rel.display_title()),@@ -584,5 +584,9 @@ mod tests {584584 "label {label}"585585 );586586 }587+ // m6/cards2 (f0rge #47): card DOM order is title-first.588+ let title = index.find("data-label=\"title\"").expect("title cell");589+ let ver = index.find("data-label=\"version\"").expect("version cell");590+ assert!(title < ver, "card DOM: title precedes version");587591 }588592 }
static/style.css+21 −16--- a/static/style.css+++ b/static/style.css@@ -229,21 +229,26 @@ details.clonebox:not([open]){padding-bottom:.25rem}229229 Desktop (>=768px) keeps .table-scroll horizontal scroll untouched above.230230 Narrow: no scroll (overflow visible), thead clipped for SR only, each231231 tr becomes a bordered card, each td a labeled flex row via data-label.232- Title cells lead bold without a repeated label; nothing is deleted. */232+ Title cells lead bold without a repeated label; nothing is deleted.233+ File table exempt (m6/cards2, f0rge #46): dense reference data stays a234+ real table at every width — .file-scroll keeps horizontal scroll and235+ table layout on narrow while every other list table becomes cards. */233236 @media (max-width:767px){234- .table-scroll{overflow-x:visible}235- .table-scroll table,.file-table table{width:100%;min-width:0}236- .table-scroll thead{position:absolute;max-width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}237- .table-scroll tbody,.table-scroll tr{display:block;width:auto}238- .table-scroll tr{border:1px solid var(--border);background:var(--bg-alt);margin:0 0 .75rem;padding:.25rem 0}239- .table-scroll th,.table-scroll td,.file-table th:nth-child(3),.file-table td:nth-child(3){white-space:normal}240- .table-scroll td{display:flex;gap:.5rem;align-items:baseline;padding:.4rem .75rem;border:none;border-bottom:1px solid var(--border);min-width:0;overflow-wrap:anywhere}241- .table-scroll td:last-child{border-bottom:none}242- .table-scroll td::before{content:attr(data-label);flex:0 0 6rem;color:var(--muted);font-weight:600;font-size:.8rem;overflow-wrap:anywhere}243- .table-scroll td.title::before{display:none}244- .table-scroll td.title{font-weight:700;font-size:1.02rem;min-width:0}245- .table-scroll td.num,.table-scroll td.sha{width:auto}246- .table-scroll td code,.table-scroll td a{overflow-wrap:anywhere;word-break:break-all;min-width:0}247- .table-scroll tbody tr:hover td{background:none}248- .table-scroll td.trunc,.trunc{white-space:normal;max-width:none;overflow:visible;text-overflow:clip}237+ .table-scroll:not(.file-scroll){overflow-x:visible}238+ .table-scroll:not(.file-scroll) table{width:100%;min-width:0}239+ .table-scroll:not(.file-scroll) thead{position:absolute;max-width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}240+ .table-scroll:not(.file-scroll) tbody,.table-scroll:not(.file-scroll) tr{display:block;width:auto}241+ .table-scroll:not(.file-scroll) tr{border:1px solid var(--border);background:var(--bg-alt);margin:0 0 .75rem;padding:.25rem 0}242+ .table-scroll:not(.file-scroll) th,.table-scroll:not(.file-scroll) td{white-space:normal}243+ .table-scroll:not(.file-scroll) td{display:flex;gap:.5rem;align-items:baseline;padding:.4rem .75rem;border:none;border-bottom:1px solid var(--border);min-width:0;overflow-wrap:anywhere}244+ .table-scroll:not(.file-scroll) td:last-child{border-bottom:none}245+ .table-scroll:not(.file-scroll) td::before{content:attr(data-label);flex:0 0 6rem;color:var(--muted);font-weight:600;font-size:.8rem;overflow-wrap:anywhere}246+ .table-scroll:not(.file-scroll) td.title::before{display:none}247+ .table-scroll:not(.file-scroll) td.title{font-weight:700;font-size:1.02rem;min-width:0}248+ .table-scroll:not(.file-scroll) td.num,.table-scroll:not(.file-scroll) td.sha{width:auto}249+ .table-scroll:not(.file-scroll) td code,.table-scroll:not(.file-scroll) td a{overflow-wrap:anywhere;word-break:break-all;min-width:0}250+ .table-scroll:not(.file-scroll) tbody tr:hover td{background:none}251+ .table-scroll:not(.file-scroll) td.trunc,.trunc{white-space:normal;max-width:none;overflow:visible;text-overflow:clip}252+ .file-scroll{overflow-x:auto}253+ .file-scroll table{width:max-content;min-width:100%}249254 }
tests/forge_readers.rs+5 −5--- a/tests/forge_readers.rs+++ b/tests/forge_readers.rs@@ -224,19 +224,19 @@ fn forge_fixture_renders_counts_numbers_and_ci() {224224 225225 // --- issues index: 2 rendered rows (broken one skipped) ---226226 let issues = read("issues/index.html");227- let rows = issues.matches("<tr><td class=\"num").count();227+ let rows = issues.matches("<tr><td class=\"title").count();228228 assert_eq!(rows, 2, "rendered issues match file-count minus broken");229229 assert!(!issues.contains("No title here"), "broken issue skipped");230230 // 5-number spot check (1): #1 links the older uuid, #2 the newer uuid.231231 assert!(232232 issues.contains(&format!(233- "<td class=\"num trunc\" data-label=\"#\" title=\"1\">1</td><td class=\"title trunc trunc-title\" data-label=\"title\" title=\"Older issue\"><a href=\"/issues/{OLDER_UUID}.html\">"233+ "<td class=\"title trunc trunc-title\" data-label=\"title\" title=\"Older issue\"><a href=\"/issues/{OLDER_UUID}.html\">Older issue</a></td><td class=\"num trunc\" data-label=\"#\" title=\"1\">1</td>"234234 )),235235 "issue #1 -> older uuid"236236 );237237 assert!(238238 issues.contains(&format!(239- "<td class=\"num trunc\" data-label=\"#\" title=\"2\">2</td><td class=\"title trunc trunc-title\" data-label=\"title\" title=\"Newer issue\"><a href=\"/issues/{NEWER_UUID}.html\">"239+ "<td class=\"title trunc trunc-title\" data-label=\"title\" title=\"Newer issue\"><a href=\"/issues/{NEWER_UUID}.html\">Newer issue</a></td><td class=\"num trunc\" data-label=\"#\" title=\"2\">2</td>"240240 )),241241 "issue #2 -> newer uuid"242242 );@@ -263,13 +263,13 @@ fn forge_fixture_renders_counts_numbers_and_ci() {263263 // (4): pulls — same shape + head/base/draft/ci + patch <pre>.264264 let pulls = read("pulls/index.html");265265 assert_eq!(266- pulls.matches("<tr><td class=\"num").count(),266+ pulls.matches("<tr><td class=\"title").count(),267267 1,268268 "prs match file-count"269269 );270270 assert!(271271 pulls.contains(&format!(272- "<td class=\"num trunc\" data-label=\"#\" title=\"1\">1</td><td class=\"title trunc trunc-title\" data-label=\"title\" title=\"Fix the thing\"><a href=\"/pulls/{PR_UUID}.html\">"272+ "<td class=\"title trunc trunc-title\" data-label=\"title\" title=\"Fix the thing\"><a href=\"/pulls/{PR_UUID}.html\">Fix the thing</a></td><td class=\"num trunc\" data-label=\"#\" title=\"1\">1</td>"273273 )),274274 "pr #1 -> uuid"275275 );
tests/releases_api.rs+5 −3--- a/tests/releases_api.rs+++ b/tests/releases_api.rs@@ -154,12 +154,14 @@ fn releases_artifacts_api_agents_feed() {154154 155155 // --- api counts == html counts (same struct pass) ---156156 let issues_html = read("issues/index.html")157- .matches("<tr><td class=\"num")157+ .matches("<tr><td class=\"title")158158 .count();159159 let pulls_html = read("pulls/index.html")160- .matches("<tr><td class=\"num")160+ .matches("<tr><td class=\"title")161+ .count();162+ let commits_html = read("commits.html")163+ .matches("<tr><td class=\"title")161164 .count();162- let commits_html = read("commits.html").matches("<tr><td class=\"sha").count();163165 let releases_html = read("releases/index.html").matches("<tr><td").count();164166 let wiki_html = read("wiki/index.html")165167 .matches("<li><a href=\"/wiki/")
tests/truncate.rs+16 −3--- a/tests/truncate.rs+++ b/tests/truncate.rs@@ -135,6 +135,12 @@ fn build_evil_fixture() -> (PathBuf, String, String) {135135 }136136 137137 fn assert_every_td_truncated(html: &str, page: &str) {138+ // m6/cards2 (f0rge #46): the file-table page (index.html) stays a real139+ // table — trunc + title= kept, no data-label card treatment.140+ assert_every_td_truncated_opts(html, page, page != "index.html");141+}142+143+fn assert_every_td_truncated_opts(html: &str, page: &str, expect_labels: bool) {138144 let parts: Vec<&str> = html.split("<td").skip(1).collect();139145 assert!(!parts.is_empty(), "{page} has cells");140146 for (i, p) in parts.iter().enumerate() {@@ -147,9 +153,17 @@ fn assert_every_td_truncated(html: &str, page: &str) {147153 head.contains("title="),148154 "{page} td #{i} carries title= (got {head:?})"149155 );156+ if expect_labels {157+ assert!(158+ head.contains("data-label="),159+ "{page} td #{i} keeps data-label (got {head:?})"160+ );161+ }162+ }163+ if !expect_labels {150164 assert!(151- head.contains("data-label="),152- "{page} td #{i} keeps data-label (got {head:?})"165+ !html.contains("data-label="),166+ "{page} has no card data-labels"153167 );154168 }155169 }156--
Comments (0)
No comments yet.
Reviews (0)
No reviews yet.